aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYana Stamcheva <yana@jitsi.org>2012-09-23 17:23:33 +0000
committerYana Stamcheva <yana@jitsi.org>2012-09-23 17:23:33 +0000
commit86a0325947316d5e4b229a7f178f87a4f12be52c (patch)
treec83d09fad6da0566b0f4f310ce651da5660c9674
parent9dfae463286f44520f3ce9dda3e4ea01ff35f852 (diff)
downloadjitsi-86a0325947316d5e4b229a7f178f87a4f12be52c.zip
jitsi-86a0325947316d5e4b229a7f178f87a4f12be52c.tar.gz
jitsi-86a0325947316d5e4b229a7f178f87a4f12be52c.tar.bz2
New enhanced interface.
-rw-r--r--resources/colors/colors.properties24
-rw-r--r--resources/images/images.properties33
-rw-r--r--resources/images/impl/gui/buttons/addAccount.pngbin1369 -> 1840 bytes
-rw-r--r--resources/images/impl/gui/buttons/addAccountMenu.pngbin864 -> 1470 bytes
-rw-r--r--resources/images/impl/gui/buttons/addContactSmall.pngbin1561 -> 1346 bytes
-rw-r--r--resources/images/impl/gui/buttons/addContactSmallPressed.pngbin1575 -> 1522 bytes
-rw-r--r--resources/images/impl/gui/buttons/addToCall.pngbin413 -> 1734 bytes
-rw-r--r--resources/images/impl/gui/buttons/addToChat.pngbin989 -> 1617 bytes
-rw-r--r--resources/images/impl/gui/buttons/callButton.pngbin1354 -> 1892 bytes
-rw-r--r--resources/images/impl/gui/buttons/callButtonPressed.pngbin1351 -> 2095 bytes
-rw-r--r--resources/images/impl/gui/buttons/callDesktopSharing.pngbin474 -> 1493 bytes
-rw-r--r--resources/images/impl/gui/buttons/callHistoryButton.pngbin1185 -> 2381 bytes
-rw-r--r--resources/images/impl/gui/buttons/callHistoryButtonPressed.pngbin1265 -> 2180 bytes
-rw-r--r--resources/images/impl/gui/buttons/callInfo.pngbin273 -> 1279 bytes
-rw-r--r--resources/images/impl/gui/buttons/callSettingButton.pngbin754 -> 1033 bytes
-rw-r--r--resources/images/impl/gui/buttons/callSettingButtonPressed.pngbin804 -> 1112 bytes
-rw-r--r--resources/images/impl/gui/buttons/callSmall.pngbin1480 -> 1361 bytes
-rw-r--r--resources/images/impl/gui/buttons/callSmallPressed.pngbin1494 -> 1592 bytes
-rw-r--r--resources/images/impl/gui/buttons/callVideoSmall.pngbin1408 -> 1282 bytes
-rw-r--r--resources/images/impl/gui/buttons/callVideoSmallPressed.pngbin1427 -> 1430 bytes
-rw-r--r--resources/images/impl/gui/buttons/chatCall.pngbin919 -> 1599 bytes
-rw-r--r--resources/images/impl/gui/buttons/chatDesktopSharing.pngbin951 -> 1574 bytes
-rw-r--r--resources/images/impl/gui/buttons/chatRoomConfig.pngbin800 -> 2107 bytes
-rw-r--r--resources/images/impl/gui/buttons/chatSmall.pngbin1531 -> 1405 bytes
-rw-r--r--resources/images/impl/gui/buttons/chatSmallPressed.pngbin1514 -> 1596 bytes
-rw-r--r--resources/images/impl/gui/buttons/chatSmallWhite.pngbin653 -> 1636 bytes
-rw-r--r--resources/images/impl/gui/buttons/chatVideoCall.pngbin0 -> 859 bytes
-rw-r--r--resources/images/impl/gui/buttons/close.pngbin685 -> 1347 bytes
-rw-r--r--resources/images/impl/gui/buttons/closeTab.pngbin583 -> 1309 bytes
-rw-r--r--resources/images/impl/gui/buttons/contactListButtonBgLeft.pngbin0 -> 1079 bytes
-rw-r--r--resources/images/impl/gui/buttons/contactListButtonBgMiddle.pngbin0 -> 1025 bytes
-rw-r--r--resources/images/impl/gui/buttons/contactListButtonBgRight.pngbin0 -> 1077 bytes
-rw-r--r--resources/images/impl/gui/buttons/contactListButtonSeparator.pngbin0 -> 999 bytes
-rw-r--r--resources/images/impl/gui/buttons/contactListDialButton.pngbin1309 -> 1945 bytes
-rw-r--r--resources/images/impl/gui/buttons/contactListOneButtonBg.pngbin0 -> 1104 bytes
-rw-r--r--resources/images/impl/gui/buttons/copy.pngbin446 -> 1160 bytes
-rw-r--r--resources/images/impl/gui/buttons/cut.pngbin631 -> 1812 bytes
-rw-r--r--resources/images/impl/gui/buttons/desktopSharingSmall.pngbin1436 -> 1388 bytes
-rw-r--r--resources/images/impl/gui/buttons/desktopSharingSmallPressed.pngbin1437 -> 1494 bytes
-rw-r--r--resources/images/impl/gui/buttons/dialButton.pngbin735 -> 1866 bytes
-rwxr-xr-xresources/images/impl/gui/buttons/encrypted_verified.pngbin1020 -> 543 bytes
-rw-r--r--resources/images/impl/gui/buttons/enterFullScreen.pngbin322 -> 1435 bytes
-rw-r--r--resources/images/impl/gui/buttons/exitFullScreen.pngbin359 -> 571 bytes
-rw-r--r--resources/images/impl/gui/buttons/hangupButton.pngbin1242 -> 1693 bytes
-rw-r--r--resources/images/impl/gui/buttons/hangupButtonPressed.pngbin1279 -> 1844 bytes
-rw-r--r--resources/images/impl/gui/buttons/hdVideo.pngbin390 -> 1482 bytes
-rw-r--r--resources/images/impl/gui/buttons/history.pngbin1309 -> 1602 bytes
-rw-r--r--resources/images/impl/gui/buttons/holdButton.pngbin225 -> 1279 bytes
-rw-r--r--resources/images/impl/gui/buttons/holdButtonPressed.pngbin712 -> 1266 bytes
-rw-r--r--resources/images/impl/gui/buttons/infoIcon.pngbin473 -> 987 bytes
-rw-r--r--resources/images/impl/gui/buttons/loVideo.pngbin388 -> 1549 bytes
-rw-r--r--resources/images/impl/gui/buttons/localVideoButton.pngbin366 -> 1487 bytes
-rw-r--r--resources/images/impl/gui/buttons/localVideoButtonPressed.pngbin983 -> 1494 bytes
-rw-r--r--resources/images/impl/gui/buttons/muteButton.pngbin666 -> 1940 bytes
-rw-r--r--resources/images/impl/gui/buttons/muteButtonPressed.pngbin668 -> 1941 bytes
-rw-r--r--resources/images/impl/gui/buttons/next.pngbin605 -> 1346 bytes
-rw-r--r--resources/images/impl/gui/buttons/paste.pngbin535 -> 1162 bytes
-rw-r--r--resources/images/impl/gui/buttons/previous.pngbin587 -> 1343 bytes
-rw-r--r--resources/images/impl/gui/buttons/recordButton.pngbin327 -> 1920 bytes
-rw-r--r--resources/images/impl/gui/buttons/recordButtonPressed.pngbin918 -> 1907 bytes
-rw-r--r--resources/images/impl/gui/buttons/save.pngbin580 -> 1071 bytes
-rw-r--r--resources/images/impl/gui/buttons/sdVideo.pngbin410 -> 1616 bytes
-rw-r--r--resources/images/impl/gui/buttons/searchCallIcon.pngbin635 -> 1474 bytes
-rw-r--r--resources/images/impl/gui/buttons/searchCallRolloverIcon.pngbin625 -> 1802 bytes
-rw-r--r--resources/images/impl/gui/buttons/secureAudioOff.pngbin587 -> 736 bytes
-rw-r--r--resources/images/impl/gui/buttons/secureAudioOn.pngbin687 -> 781 bytes
-rw-r--r--resources/images/impl/gui/buttons/secureVideoOff.pngbin584 -> 579 bytes
-rw-r--r--resources/images/impl/gui/buttons/secureVideoOn.pngbin655 -> 585 bytes
-rw-r--r--resources/images/impl/gui/buttons/sendFile.pngbin662 -> 1307 bytes
-rw-r--r--resources/images/impl/gui/buttons/showHideLocalVideo.pngbin366 -> 1606 bytes
-rw-r--r--resources/images/impl/gui/buttons/showHideLocalVideoPressed.pngbin1075 -> 1596 bytes
-rw-r--r--resources/images/impl/gui/buttons/smiley.pngbin1339 -> 1937 bytes
-rw-r--r--resources/images/impl/gui/buttons/transferCallButton.pngbin483 -> 2114 bytes
-rw-r--r--resources/images/impl/gui/buttons/videoCallButton.pngbin1304 -> 1502 bytes
-rw-r--r--resources/images/impl/gui/buttons/videoCallButtonPressed.pngbin1216 -> 1635 bytes
-rw-r--r--resources/images/impl/gui/buttons/volumeControl.pngbin431 -> 1645 bytes
-rw-r--r--resources/images/impl/gui/common/addContact16x16.pngbin780 -> 1410 bytes
-rw-r--r--resources/images/impl/gui/common/addContactDialogIcon.pngbin2892 -> 3074 bytes
-rw-r--r--resources/images/impl/gui/common/addGroup.pngbin3293 -> 4132 bytes
-rw-r--r--resources/images/impl/gui/common/admin.pngbin835 -> 1698 bytes
-rw-r--r--resources/images/impl/gui/common/browser16x16.pngbin774 -> 1939 bytes
-rw-r--r--resources/images/impl/gui/common/call16x16.pngbin741 -> 1418 bytes
-rw-r--r--resources/images/impl/gui/common/callHistoryButtonNotification.pngbin0 -> 1726 bytes
-rw-r--r--resources/images/impl/gui/common/callToolbarSeparator.pngbin0 -> 972 bytes
-rw-r--r--resources/images/impl/gui/common/changeNickname16x16.pngbin808 -> 1531 bytes
-rw-r--r--resources/images/impl/gui/common/changeSubject16x16.pngbin744 -> 1420 bytes
-rw-r--r--resources/images/impl/gui/common/chatRoom16x16.pngbin861 -> 1421 bytes
-rw-r--r--resources/images/impl/gui/common/closedGroup.pngbin404 -> 1250 bytes
-rw-r--r--resources/images/impl/gui/common/delete16x16.pngbin693 -> 1404 bytes
-rw-r--r--resources/images/impl/gui/common/desktopSharing16x16.pngbin561 -> 1280 bytes
-rw-r--r--resources/images/impl/gui/common/downArrow.pngbin268 -> 1053 bytes
-rw-r--r--resources/images/impl/gui/common/envelope.pngbin410 -> 1249 bytes
-rw-r--r--resources/images/impl/gui/common/groups16x16.pngbin861 -> 1511 bytes
-rw-r--r--resources/images/impl/gui/common/hdVideo.pngbin0 -> 1482 bytes
-rw-r--r--resources/images/impl/gui/common/history16x16.pngbin971 -> 1609 bytes
-rw-r--r--resources/images/impl/gui/common/incomingCall.pngbin965 -> 1706 bytes
-rw-r--r--resources/images/impl/gui/common/incomingCallBgLeft.pngbin0 -> 1102 bytes
-rw-r--r--resources/images/impl/gui/common/incomingCallBgMiddle.pngbin0 -> 1018 bytes
-rw-r--r--resources/images/impl/gui/common/incomingCallBgRight.pngbin0 -> 1107 bytes
-rw-r--r--resources/images/impl/gui/common/leave.pngbin522 -> 1380 bytes
-rw-r--r--resources/images/impl/gui/common/leaveold.pngbin0 -> 1609 bytes
-rw-r--r--resources/images/impl/gui/common/loVideo.pngbin0 -> 1549 bytes
-rw-r--r--resources/images/impl/gui/common/missedCall.pngbin1108 -> 1700 bytes
-rw-r--r--resources/images/impl/gui/common/moderator.pngbin792 -> 1617 bytes
-rw-r--r--resources/images/impl/gui/common/moveContact.pngbin775 -> 1432 bytes
-rw-r--r--resources/images/impl/gui/common/moveToGroup16x16.pngbin775 -> 1446 bytes
-rw-r--r--resources/images/impl/gui/common/noSound.pngbin0 -> 348 bytes
-rw-r--r--resources/images/impl/gui/common/openedGroup.pngbin342 -> 1232 bytes
-rw-r--r--resources/images/impl/gui/common/outgoingCall.pngbin1095 -> 1753 bytes
-rw-r--r--resources/images/impl/gui/common/owner.pngbin763 -> 1730 bytes
-rw-r--r--resources/images/impl/gui/common/padlock.pngbin2826 -> 3740 bytes
-rw-r--r--resources/images/impl/gui/common/personPhoto.pngbin7055 -> 10463 bytes
-rw-r--r--resources/images/impl/gui/common/personPhotoFrame.pngbin3090 -> 1217 bytes
-rw-r--r--resources/images/impl/gui/common/personPhotoSmall.pngbin0 -> 2117 bytes
-rw-r--r--resources/images/impl/gui/common/regionSharing16x16.pngbin622 -> 1129 bytes
-rw-r--r--resources/images/impl/gui/common/rename16x16.pngbin651 -> 1455 bytes
-rw-r--r--resources/images/impl/gui/common/renameDialogIcon.pngbin16876 -> 3873 bytes
-rw-r--r--resources/images/impl/gui/common/searchIcon.pngbin363 -> 1533 bytes
-rw-r--r--resources/images/impl/gui/common/sendFile16x16.pngbin548 -> 1150 bytes
-rw-r--r--resources/images/impl/gui/common/sendMessage16x16.pngbin522 -> 1142 bytes
-rw-r--r--resources/images/impl/gui/common/separator.pngbin0 -> 1034 bytes
-rw-r--r--resources/images/impl/gui/common/showHideOffline.pngbin822 -> 1529 bytes
-rw-r--r--resources/images/impl/gui/common/silent.pngbin526 -> 1579 bytes
-rw-r--r--resources/images/impl/gui/common/soundMenu.pngbin703 -> 1672 bytes
-rw-r--r--resources/images/impl/gui/common/soundlevel/Headphone.pngbin441 -> 1618 bytes
-rw-r--r--resources/images/impl/gui/common/soundlevel/Microphone.pngbin353 -> 1696 bytes
-rw-r--r--resources/images/impl/gui/common/soundlevel/soundActiveLeft.pngbin0 -> 1276 bytes
-rw-r--r--resources/images/impl/gui/common/soundlevel/soundActiveLeftGradient.pngbin0 -> 1641 bytes
-rw-r--r--resources/images/impl/gui/common/soundlevel/soundActiveMiddle.pngbin0 -> 1055 bytes
-rw-r--r--resources/images/impl/gui/common/soundlevel/soundActiveRight.pngbin0 -> 1587 bytes
-rw-r--r--resources/images/impl/gui/common/soundlevel/soundActiveRightGradient.pngbin0 -> 1510 bytes
-rw-r--r--resources/images/impl/gui/common/soundlevel/soundInactiveLeft.pngbin0 -> 1167 bytes
-rw-r--r--resources/images/impl/gui/common/soundlevel/soundInactiveMiddle.pngbin0 -> 1024 bytes
-rw-r--r--resources/images/impl/gui/common/soundlevel/soundInactiveRight.pngbin0 -> 1170 bytes
-rw-r--r--resources/images/impl/gui/common/soundlevel/volumeButton.pngbin578 -> 507 bytes
-rw-r--r--resources/images/impl/gui/common/soundlevel/volumeButtonPressed.pngbin658 -> 491 bytes
-rw-r--r--resources/images/impl/gui/common/standard.pngbin789 -> 1527 bytes
-rw-r--r--resources/images/impl/gui/common/statusicons/away.pngbin610 -> 1478 bytes
-rw-r--r--resources/images/impl/gui/common/statusicons/dnd.pngbin567 -> 1416 bytes
-rw-r--r--resources/images/impl/gui/common/statusicons/freeForChat.pngbin674 -> 1552 bytes
-rw-r--r--resources/images/impl/gui/common/statusicons/offline.pngbin584 -> 1378 bytes
-rw-r--r--resources/images/impl/gui/common/statusicons/online.pngbin619 -> 1441 bytes
-rw-r--r--resources/images/impl/gui/common/unauthorizedContact16x16.pngbin839 -> 1582 bytes
-rw-r--r--resources/images/impl/gui/common/videoCall16x16.pngbin473 -> 1078 bytes
-rw-r--r--resources/images/impl/gui/common/voicemail.pngbin1013 -> 1853 bytes
-rw-r--r--resources/images/impl/gui/lookandfeel/blueBackground.pngbin0 -> 946 bytes
-rw-r--r--resources/images/impl/gui/lookandfeel/blueBackgroundRight.pngbin0 -> 927 bytes
-rw-r--r--resources/images/impl/gui/lookandfeel/blueCurves.pngbin0 -> 1484 bytes
-rw-r--r--resources/images/impl/gui/lookandfeel/blueCurvesTop.pngbin0 -> 698 bytes
-rw-r--r--resources/images/impl/gui/lookandfeel/blueIndicator.pngbin0 -> 1046 bytes
-rwxr-xr-xresources/images/impl/gui/lookandfeel/box-bg.pngbin0 -> 3134 bytes
-rw-r--r--resources/images/impl/gui/lookandfeel/chatLine.pngbin0 -> 204 bytes
-rw-r--r--resources/images/impl/gui/lookandfeel/selectedTabLeft.pngbin392 -> 1178 bytes
-rw-r--r--resources/images/impl/gui/lookandfeel/selectedTabMiddle.pngbin251 -> 1055 bytes
-rw-r--r--resources/images/impl/gui/lookandfeel/selectedTabRight.pngbin421 -> 1216 bytes
-rw-r--r--resources/images/impl/gui/lookandfeel/tabLeft.pngbin359 -> 1088 bytes
-rw-r--r--resources/images/impl/gui/lookandfeel/tabMiddle.pngbin242 -> 1027 bytes
-rw-r--r--resources/images/impl/gui/lookandfeel/tabRight.pngbin387 -> 1105 bytes
-rw-r--r--resources/images/impl/gui/lookandfeel/yellowBackground.pngbin0 -> 946 bytes
-rw-r--r--resources/images/impl/gui/lookandfeel/yellowBackgroundRight.pngbin0 -> 927 bytes
-rw-r--r--resources/images/impl/gui/lookandfeel/yellowCurves.pngbin0 -> 1484 bytes
-rw-r--r--resources/images/impl/gui/lookandfeel/yellowCurvesTop.pngbin0 -> 698 bytes
-rw-r--r--resources/images/impl/gui/lookandfeel/yellowIndicator.pngbin0 -> 1045 bytes
-rw-r--r--resources/images/impl/media/audioConfig.pngbin1202 -> 1415 bytes
-rw-r--r--resources/images/impl/media/videoConfig.pngbin625 -> 1553 bytes
-rw-r--r--resources/images/impl/systray/dock-away.pngbin11300 -> 13559 bytes
-rw-r--r--resources/images/impl/systray/dock-chatty.pngbin11711 -> 13693 bytes
-rw-r--r--resources/images/impl/systray/dock-dnd.pngbin10912 -> 12990 bytes
-rw-r--r--resources/images/impl/systray/dock-offline.pngbin11390 -> 12357 bytes
-rw-r--r--resources/images/impl/systray/dock-online.pngbin9880 -> 11247 bytes
-rw-r--r--resources/images/impl/systray/envelope.pngbin822 -> 1748 bytes
-rw-r--r--resources/images/impl/systray/envelopeMacOSX.pngbin199 -> 1507 bytes
-rw-r--r--resources/images/impl/systray/envelopeMacOSXWhite.pngbin198 -> 1502 bytes
-rw-r--r--resources/images/impl/systray/envelopeWindows.pngbin1068 -> 2382 bytes
-rw-r--r--resources/images/impl/systray/systrayIcon.pngbin792 -> 1645 bytes
-rw-r--r--resources/images/impl/systray/systrayIconAway.pngbin822 -> 1754 bytes
-rw-r--r--resources/images/impl/systray/systrayIconDND.pngbin929 -> 1731 bytes
-rw-r--r--resources/images/impl/systray/systrayIconFFC.pngbin895 -> 1828 bytes
-rw-r--r--resources/images/impl/systray/systrayIconOffline.pngbin441 -> 1623 bytes
-rw-r--r--resources/images/impl/systray/systrayIconWindows.pngbin1301 -> 2186 bytes
-rw-r--r--resources/images/impl/systray/systrayIconWindowsAway.pngbin1388 -> 2362 bytes
-rw-r--r--resources/images/impl/systray/systrayIconWindowsDND.pngbin1452 -> 2334 bytes
-rw-r--r--resources/images/impl/systray/systrayIconWindowsFFC.pngbin1426 -> 2444 bytes
-rw-r--r--resources/images/impl/systray/systrayIconWindowsOffline.pngbin772 -> 1994 bytes
-rw-r--r--resources/images/plugin/advancedconfig/configIcon.pngbin1304 -> 2249 bytes
-rw-r--r--resources/images/plugin/chatconfig/chatIcon.pngbin977 -> 1583 bytes
-rw-r--r--resources/images/plugin/contactinfo/userInfo16x16.pngbin465 -> 1345 bytes
-rw-r--r--resources/images/plugin/generalconfig/configureIcon.pngbin893 -> 1301 bytes
-rw-r--r--resources/images/plugin/notificationconfiguration/folder.pngbin1305 -> 1306 bytes
-rw-r--r--resources/images/plugin/notificationconfiguration/playIcon.pngbin590 -> 1354 bytes
-rw-r--r--resources/images/plugin/notificationconfiguration/popupIcon.pngbin429 -> 1290 bytes
-rw-r--r--resources/images/plugin/notificationconfiguration/progIcon.pngbin589 -> 1510 bytes
-rw-r--r--resources/images/plugin/notificationconfiguration/soundIcon.pngbin492 -> 1254 bytes
-rw-r--r--resources/images/plugin/otr/encrypted22x22.pngbin699 -> 1368 bytes
-rw-r--r--resources/images/plugin/otr/encrypted_unverified22x22.pngbin832 -> 1774 bytes
-rw-r--r--resources/images/plugin/otr/finished22x22.pngbin820 -> 1839 bytes
-rw-r--r--resources/images/plugin/otr/otr_menu_icon.pngbin708 -> 1136 bytes
-rw-r--r--resources/images/plugin/otr/plaintext16x16.pngbin612 -> 1438 bytes
-rw-r--r--resources/images/plugin/otr/plaintext22x22.pngbin717 -> 1428 bytes
-rw-r--r--resources/images/plugin/securityconfig/security.pngbin920 -> 2510 bytes
-rw-r--r--resources/images/protocol/aim/aim16x16-away.pngbin531 -> 1877 bytes
-rw-r--r--resources/images/protocol/aim/aim16x16-invisible.pngbin604 -> 1880 bytes
-rw-r--r--resources/images/protocol/aim/aim16x16-offline.pngbin621 -> 1613 bytes
-rw-r--r--resources/images/protocol/aim/aim16x16-online.pngbin623 -> 1532 bytes
-rw-r--r--resources/images/protocol/aim/cr16-action-aim_connecting.pngbin0 -> 1764 bytes
-rw-r--r--resources/images/protocol/facebook/facebook-idle.pngbin3332 -> 1706 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-away.pngbin3203 -> 1755 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-connecting.pngbin0 -> 1655 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-dnd.pngbin710 -> 1720 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-ffc.pngbin756 -> 1847 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-invisible.pngbin0 -> 1756 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-offline.pngbin567 -> 1350 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-online.pngbin552 -> 1426 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-phone.pngbin818 -> 1761 bytes
-rw-r--r--resources/images/protocol/facebook/status16x16-xa.pngbin3332 -> 1726 bytes
-rw-r--r--resources/images/protocol/gibberish/gibberish-away.pngbin1008 -> 2085 bytes
-rw-r--r--resources/images/protocol/gibberish/gibberish-dnd.pngbin1108 -> 2057 bytes
-rw-r--r--resources/images/protocol/gibberish/gibberish-ffc.pngbin1124 -> 2130 bytes
-rw-r--r--resources/images/protocol/gibberish/gibberish-invisible.pngbin1014 -> 2125 bytes
-rw-r--r--resources/images/protocol/gibberish/gibberish-na.pngbin1121 -> 2079 bytes
-rw-r--r--resources/images/protocol/gibberish/gibberish-occupied.pngbin1125 -> 2061 bytes
-rw-r--r--resources/images/protocol/gibberish/gibberish-offline.pngbin941 -> 1823 bytes
-rw-r--r--resources/images/protocol/gibberish/gibberish-online.pngbin992 -> 2055 bytes
-rw-r--r--resources/images/protocol/googletalk/status16x16-away.pngbin562 -> 1867 bytes
-rw-r--r--resources/images/protocol/googletalk/status16x16-connecting.pngbin0 -> 1777 bytes
-rw-r--r--resources/images/protocol/googletalk/status16x16-dnd.pngbin748 -> 1843 bytes
-rw-r--r--resources/images/protocol/googletalk/status16x16-ffc.pngbin947 -> 1951 bytes
-rw-r--r--resources/images/protocol/googletalk/status16x16-offline.pngbin495 -> 1636 bytes
-rw-r--r--resources/images/protocol/googletalk/status16x16-online.pngbin815 -> 1631 bytes
-rw-r--r--resources/images/protocol/googletalk/status16x16-phone.pngbin890 -> 1905 bytes
-rw-r--r--resources/images/protocol/googletalk/status16x16-xa.pngbin618 -> 1845 bytes
-rw-r--r--resources/images/protocol/icq/cr16-action-icq_connecting-1.pngbin0 -> 1885 bytes
-rw-r--r--resources/images/protocol/icq/googletalk3_157.pngbin0 -> 1987 bytes
-rw-r--r--resources/images/protocol/icq/icq16x16-away.pngbin438 -> 1954 bytes
-rw-r--r--resources/images/protocol/icq/icq16x16-dnd.pngbin832 -> 1937 bytes
-rw-r--r--resources/images/protocol/icq/icq16x16-ffc.pngbin870 -> 2022 bytes
-rw-r--r--resources/images/protocol/icq/icq16x16-invisible.pngbin1009 -> 1984 bytes
-rw-r--r--resources/images/protocol/icq/icq16x16-na.pngbin714 -> 1946 bytes
-rw-r--r--resources/images/protocol/icq/icq16x16-occupied.pngbin912 -> 1916 bytes
-rw-r--r--resources/images/protocol/icq/icq16x16-offline.pngbin643 -> 1793 bytes
-rw-r--r--resources/images/protocol/icq/icq16x16-online.pngbin817 -> 1774 bytes
-rw-r--r--resources/images/protocol/ippi/sip16x16-away.pngbin730 -> 1963 bytes
-rw-r--r--resources/images/protocol/ippi/sip16x16-busy.pngbin705 -> 1916 bytes
-rw-r--r--resources/images/protocol/ippi/sip16x16-offline.pngbin363 -> 1573 bytes
-rw-r--r--resources/images/protocol/ippi/sip16x16-online.pngbin615 -> 1830 bytes
-rw-r--r--resources/images/protocol/ippi/sip16x16-phone.pngbin730 -> 1967 bytes
-rw-r--r--resources/images/protocol/iptel/sip-connecting.pngbin0 -> 1901 bytes
-rw-r--r--resources/images/protocol/iptel/sip16x16-away.pngbin962 -> 2007 bytes
-rw-r--r--resources/images/protocol/iptel/sip16x16-busy.pngbin960 -> 1977 bytes
-rw-r--r--resources/images/protocol/iptel/sip16x16-offline.pngbin550 -> 1766 bytes
-rw-r--r--resources/images/protocol/iptel/sip16x16-online.pngbin948 -> 1823 bytes
-rw-r--r--resources/images/protocol/iptel/sip16x16-phone.pngbin1006 -> 2003 bytes
-rw-r--r--resources/images/protocol/irc/cr16-action-irc_away.pngbin703 -> 1946 bytes
-rw-r--r--resources/images/protocol/irc/cr16-action-irc_connecting-1.pngbin0 -> 1818 bytes
-rw-r--r--resources/images/protocol/irc/cr16-action-irc_offline.pngbin711 -> 1675 bytes
-rw-r--r--resources/images/protocol/irc/cr16-action-irc_online.pngbin812 -> 1703 bytes
-rw-r--r--resources/images/protocol/irc/cr16-action-irc_op.pngbin651 -> 1946 bytes
-rw-r--r--resources/images/protocol/irc/cr16-action-irc_server.pngbin996 -> 1903 bytes
-rw-r--r--resources/images/protocol/irc/cr16-action-irc_voice.pngbin919 -> 1892 bytes
-rw-r--r--resources/images/protocol/irc/googletalk3_131.pngbin0 -> 1895 bytes
-rw-r--r--resources/images/protocol/jabber/status16x16-away.pngbin752 -> 1952 bytes
-rw-r--r--resources/images/protocol/jabber/status16x16-connecting.pngbin0 -> 1937 bytes
-rw-r--r--resources/images/protocol/jabber/status16x16-dnd.pngbin650 -> 1938 bytes
-rw-r--r--resources/images/protocol/jabber/status16x16-ffc.pngbin800 -> 2047 bytes
-rw-r--r--resources/images/protocol/jabber/status16x16-offline.pngbin433 -> 1653 bytes
-rw-r--r--resources/images/protocol/jabber/status16x16-online.pngbin663 -> 1867 bytes
-rw-r--r--resources/images/protocol/jabber/status16x16-phone.pngbin800 -> 2045 bytes
-rw-r--r--resources/images/protocol/jabber/status16x16-xa.pngbin787 -> 2009 bytes
-rw-r--r--resources/images/protocol/msn/msn16x16-away.pngbin879 -> 2015 bytes
-rw-r--r--resources/images/protocol/msn/msn16x16-brb.pngbin820 -> 2024 bytes
-rw-r--r--resources/images/protocol/msn/msn16x16-busy.pngbin893 -> 1996 bytes
-rw-r--r--resources/images/protocol/msn/msn16x16-connecting.pngbin0 -> 1931 bytes
-rw-r--r--resources/images/protocol/msn/msn16x16-invisible.pngbin910 -> 2035 bytes
-rw-r--r--resources/images/protocol/msn/msn16x16-lunch.pngbin876 -> 1984 bytes
-rw-r--r--resources/images/protocol/msn/msn16x16-na.pngbin723 -> 2005 bytes
-rw-r--r--resources/images/protocol/msn/msn16x16-offline.pngbin796 -> 1753 bytes
-rw-r--r--resources/images/protocol/msn/msn16x16-online.pngbin844 -> 1926 bytes
-rw-r--r--resources/images/protocol/msn/msn16x16-phone.pngbin814 -> 2045 bytes
-rw-r--r--resources/images/protocol/sip/sip-connecting.pngbin0 -> 1643 bytes
-rw-r--r--resources/images/protocol/sip/sip16x16-away.pngbin579 -> 1715 bytes
-rw-r--r--resources/images/protocol/sip/sip16x16-busy.pngbin510 -> 1676 bytes
-rw-r--r--resources/images/protocol/sip/sip16x16-offline.pngbin490 -> 1323 bytes
-rw-r--r--resources/images/protocol/sip/sip16x16-online.pngbin482 -> 1342 bytes
-rw-r--r--resources/images/protocol/sip/sip16x16-phone.pngbin623 -> 1757 bytes
-rw-r--r--resources/images/protocol/sip2sip/sip16x16-away.pngbin935 -> 2081 bytes
-rw-r--r--resources/images/protocol/sip2sip/sip16x16-busy.pngbin913 -> 2041 bytes
-rw-r--r--resources/images/protocol/sip2sip/sip16x16-offline.pngbin612 -> 1775 bytes
-rw-r--r--resources/images/protocol/sip2sip/sip16x16-online.pngbin905 -> 1859 bytes
-rw-r--r--resources/images/protocol/sip2sip/sip16x16-phone.pngbin956 -> 2075 bytes
-rw-r--r--resources/images/protocol/ssh/ssh-connected.pngbin1321 -> 1703 bytes
-rw-r--r--resources/images/protocol/ssh/ssh-connecting.pngbin1055 -> 1657 bytes
-rw-r--r--resources/images/protocol/ssh/ssh-filetransfer.pngbin1059 -> 1725 bytes
-rw-r--r--resources/images/protocol/ssh/ssh-na.pngbin1088 -> 1719 bytes
-rw-r--r--resources/images/protocol/ssh/ssh-offline.pngbin789 -> 1309 bytes
-rw-r--r--resources/images/protocol/ssh/ssh-online.pngbin1215 -> 1391 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-away.pngbin671 -> 1781 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-busy.pngbin805 -> 1736 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-connecting.pngbin0 -> 1654 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-idle.pngbin837 -> 1741 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-invisible.pngbin874 -> 1759 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-lunch.pngbin855 -> 1708 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-na.pngbin737 -> 1724 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-offline.pngbin538 -> 1485 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-online.pngbin878 -> 1514 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-phone.pngbin830 -> 1766 bytes
-rw-r--r--resources/images/protocol/yahoo/yahoo16x16-vacation.pngbin886 -> 1723 bytes
-rw-r--r--resources/images/protocol/zeroconf/zeroconf-away.pngbin728 -> 1962 bytes
-rw-r--r--resources/images/protocol/zeroconf/zeroconf-dnd.pngbin755 -> 1933 bytes
-rw-r--r--resources/images/protocol/zeroconf/zeroconf-invisible.pngbin775 -> 1967 bytes
-rw-r--r--resources/images/protocol/zeroconf/zeroconf-offline.pngbin494 -> 1673 bytes
-rw-r--r--resources/images/protocol/zeroconf/zeroconf-online.pngbin781 -> 1648 bytes
-rw-r--r--resources/styles/defaultStyle.css14
-rw-r--r--resources/styles/defaultStyle.txt65
-rw-r--r--resources/styles/stylebackup.txt1949
-rw-r--r--src/net/java/sip/communicator/impl/contactlist/MetaContactImpl.java169
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/MainFrame.java2
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/AbstractCallToggleButton.java62
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/CallHistoryButton.java39
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/CallPanel.java163
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/CallPeerRendererUtils.java130
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/CallToolBarButton.java72
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/FullScreenButton.java36
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/FullScreenLayout.java22
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/HangupButton.java42
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/InputVolumeControlButton.java12
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPanel.java9
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPeerPanel.java9
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/OutputVolumeControlButton.java208
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/TransferCallButton.java25
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/call/VolumeControlSlider.java29
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationComponent.java2
-rwxr-xr-xsrc/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java726
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/ChatHtmlUtils.java412
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java33
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/ChatTransport.java2
-rwxr-xr-xsrc/net/java/sip/communicator/impl/gui/main/chat/ChatWritePanel.java5
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/IncomingMessageStyle.java203
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/OutgoingMessageStyle.java206
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/history/HistoryWindow.java28
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/menus/ChatRightButtonMenu.java40
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/menus/FileMenu.java2
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/chat/toolBars/MainToolBar.java100
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListCellRenderer.java6
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java338
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java81
-rw-r--r--src/net/java/sip/communicator/impl/gui/main/presence/AccountStatusPanel.java34
-rw-r--r--src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java123
-rw-r--r--src/net/java/sip/communicator/util/AvatarCacheUtils.java344
-rw-r--r--src/net/java/sip/communicator/util/GuiUtils.java37
-rw-r--r--src/net/java/sip/communicator/util/ImageUtils.java2
-rw-r--r--src/net/java/sip/communicator/util/UtilActivator.java20
-rw-r--r--src/net/java/sip/communicator/util/swing/OrderedTransparentPanel.java4
-rwxr-xr-xsrc/net/java/sip/communicator/util/swing/SIPCommButton.java14
-rw-r--r--src/net/java/sip/communicator/util/swing/SIPCommTextButton.java10
-rw-r--r--src/net/java/sip/communicator/util/swing/SIPCommToggleButton.java13
-rw-r--r--src/net/java/sip/communicator/util/swing/SoundLevelIndicator.java135
-rw-r--r--src/net/java/sip/communicator/util/swing/plaf/SIPCommTabbedPaneUI.java12
-rw-r--r--src/net/java/sip/communicator/util/swing/plaf/SIPCommTextFieldUI.java6
-rw-r--r--src/net/java/sip/communicator/util/util.manifest.mf1
359 files changed, 4870 insertions, 1183 deletions
diff --git a/resources/colors/colors.properties b/resources/colors/colors.properties
index 7a9c77a..a4b9cf7 100644
--- a/resources/colors/colors.properties
+++ b/resources/colors/colors.properties
@@ -83,10 +83,10 @@ service.gui.TAB_TITLE_SELECTED=000000
service.gui.CALL_HISTORY_EVEN_ROW_COLOR=EFEFEF
# Selection color for all lists (contact list, call list, chat rooms list, etc.)
-service.gui.LIST_SELECTION_COLOR=ADD2EF
+service.gui.LIST_SELECTION_COLOR=9ae8fc
# Selection color for contact list gradient
-service.gui.LIST_SELECTION_COLOR_GRADIENT=FFFFFF
+service.gui.LIST_SELECTION_COLOR_GRADIENT=0cc0f4
# Selection border color of all lists (contact list, call list, chat rooms list, etc.)
service.gui.LIST_SELECTION_BORDER_COLOR=daeefd
@@ -131,10 +131,10 @@ plugin.simpleaccreg.ACCOUNT_REGISTRATION_BACKGROUND=C2CEE0
service.gui.LIST_ROW=E7E7E7
# Contact list group row background color.
-service.gui.CONTACT_LIST_GROUP_ROW=C3C3C3
+service.gui.CONTACT_LIST_GROUP_ROW=dde4eb
# Contact list gradient group color.
-service.gui.CONTACT_LIST_GROUP_GRADIENT=FFFFFF
+service.gui.CONTACT_LIST_GROUP_GRADIENT=e3eaf1
# Main window background color.
service.gui.MAIN_WINDOW_BACKGROUND=FFFFFF
@@ -155,10 +155,10 @@ service.gui.CONTACT_LIST_CONTACT_FOREGROUND=000000
service.gui.CONTACT_LIST_GROUP_FOREGROUND=000000
# The background color of all windows and dialogs.
-service.gui.MAIN_BACKGROUND=4A9BDB
+service.gui.MAIN_BACKGROUND=dfedf6
# The end color of the gradient painted to all windows.
-service.gui.MAIN_BACKGROUND_GRADIENT=E1F0FD
+service.gui.MAIN_BACKGROUND_GRADIENT=dcebf4
service.gui.FAVORITES_PANEL_BACKGROUND=474747
@@ -214,8 +214,16 @@ service.gui.SECURITY_ON=6FC93C
# The security off status color.
service.gui.SECURITY_OFF=ED0000
-# Going secure status color.
+# Call toolbar backgroundn color.
+service.gui.CALL_TOOL_BAR=DFDFDF
+
+# Call toolbar sound background color.
+service.gui.CALL_TOOL_BAR_SOUND_BG=282828
+
+# Call toolbar full screen background color.
+service.gui.CALL_TOOL_BAR_FULL_SCREEN=313131
+
service.gui.GOING_SECURE=FFC01B
# Chat editor correction message background color.
-service.gui.CHAT_EDIT_MESSAGE_BACKGROUND=fffbc3 \ No newline at end of file
+service.gui.CHAT_EDIT_MESSAGE_BACKGROUND=fffbc3
diff --git a/resources/images/images.properties b/resources/images/images.properties
index b969519..1151649 100644
--- a/resources/images/images.properties
+++ b/resources/images/images.properties
@@ -15,6 +15,7 @@ service.gui.WINDOW_TITLE_BAR_BG=resources/images/impl/gui/common/windowTitleBar.
service.gui.USER_PHOTO_FRAME=resources/images/impl/gui/common/personPhotoFrame.png
service.gui.USER_PHOTO_SHADOW=resources/images/impl/gui/common/personPhotoShadow.png
service.gui.DEFAULT_USER_PHOTO=resources/images/impl/gui/common/personPhoto.png
+service.gui.DEFAULT_USER_PHOTO_SMALL=resources/images/impl/gui/common/personPhotoSmall.png
# service gui icons
service.gui.icons.ADD_ICON=resources/images/impl/gui/buttons/add.png
@@ -22,6 +23,7 @@ service.gui.icons.ACCOUNT_ICON=resources/images/impl/gui/buttons/addAccount.png
service.gui.icons.ADD_ACCOUNT_MENU_ICON=resources/images/impl/gui/buttons/addAccountMenu.png
service.gui.icons.CONFIGURE_ICON=resources/images/impl/gui/common/configureIcon.png
service.gui.icons.SHOW_HIDE_OFFLINE_ICON=resources/images/impl/gui/common/showHideOffline.png
+service.gui.icons.NO_SOUND_ICON=resources/images/impl/gui/common/noSound.png
service.gui.icons.SOUND_MENU_ICON=resources/images/impl/gui/common/soundMenu.png
service.gui.icons.QUICK_MENU_ADD_ICON=resources/images/impl/gui/buttons/addContactIcon.png
service.gui.icons.QUICK_MENU_CONFIGURE_ICON=resources/images/impl/gui/buttons/configureIcon.png
@@ -34,7 +36,6 @@ service.gui.icons.QUICK_MENU_MY_CHAT_ROOMS_ICON=resources/images/impl/gui/button
service.gui.icons.SEARCH_ICON=resources/images/impl/gui/common/searchIcon.png
service.gui.icons.SEARCH_ICON_16x16=resources/images/impl/gui/common/searchIcon16x16.png
service.gui.icons.ADD_TO_CHAT_ICON=resources/images/impl/gui/buttons/addToChat.png
-service.gui.icons.RIGHT_ARROW_ICON=resources/images/impl/gui/common/rightArrow.png
service.gui.icons.DOWN_ARROW_ICON=resources/images/impl/gui/common/downArrow.png
service.gui.icons.INVITE_DIALOG_ICON=resources/images/impl/gui/common/inviteDialogIcon.png
service.gui.icons.SEND_SMS_ICON=resources/images/impl/gui/common/gsm.png
@@ -112,6 +113,8 @@ service.gui.icons.SD_VIDEO_ICON=resources/images/impl/gui/common/sdVideoIcon.png
service.gui.icons.HD_VIDEO_ICON=resources/images/impl/gui/common/hdVideoIcon.png
service.gui.icons.UNAUTHORIZED_CONTACT_PHOTO=resources/images/impl/gui/common/unauthorizedContact.png
service.gui.icons.UNAUTHORIZED_CONTACT_16x16=resources/images/impl/gui/common/unauthorizedContact16x16.png
+service.gui.icons.CALL_TOOLBAR_SEPARATOR=resources/images/impl/gui/common/callToolbarSeparator.png
+service.gui.icons.CALL_HISTORY_BUTTON_NOTIFICATION=resources/images/impl/gui/common/callHistoryButtonNotification.png
service.gui.icons.AUTO_ANSWER_CHECK=resources/images/impl/gui/common/autoAnswerCheck.png
# Status icons
@@ -125,6 +128,11 @@ service.gui.statusicons.USER_OCCUPIED_ICON=resources/images/impl/gui/common/stat
service.gui.statusicons.USER_ON_THE_PHONE_ICON=resources/images/impl/gui/common/statusicons/onThePhone.png
# service gui buttons
+service.gui.buttons.CONTACT_LIST_BUTTON_BG_LEFT=resources/images/impl/gui/buttons/contactListButtonBgLeft.png
+service.gui.buttons.CONTACT_LIST_BUTTON_BG_RIGHT=resources/images/impl/gui/buttons/contactListButtonBgRight.png
+service.gui.buttons.CONTACT_LIST_BUTTON_BG_MIDDLE=resources/images/impl/gui/buttons/contactListButtonBgMiddle.png
+service.gui.buttons.CONTACT_LIST_ONE_BUTTON_BG=resources/images/impl/gui/buttons/contactListOneButtonBg.png
+service.gui.buttons.CONTACT_LIST_BUTTON_SEPARATOR=resources/images/impl/gui/buttons/contactListButtonSeparator.png
service.gui.buttons.CALL_BUTTON_BG=resources/images/impl/gui/buttons/callButton.png
service.gui.buttons.MERGE_CALL_BUTTON_BG=resources/images/impl/gui/buttons/mergeToCall.png
service.gui.buttons.CALL_VIDEO_BUTTON_BG=resources/images/impl/gui/buttons/videoCallButton.png
@@ -240,6 +248,7 @@ service.gui.buttons.HIDE_ACTIONS_ROLLOVER_BUTTON=resources/images/impl/gui/butto
service.gui.buttons.CALL_PEER_TOOLS=resources/images/impl/gui/buttons/tools.png
service.gui.buttons.CHAT_ROOM_CONFIG=resources/images/impl/gui/buttons/chatRoomConfig.png
service.gui.buttons.CHAT_CALL=resources/images/impl/gui/buttons/chatCall.png
+service.gui.buttons.CHAT_VIDEO_CALL=resources/images/impl/gui/buttons/chatVideoCall.png
service.gui.buttons.CHAT_DESKTOP_SHARING=resources/images/impl/gui/buttons/chatDesktopSharing.png
service.gui.buttons.CALL_HISTORY_BUTTON=resources/images/impl/gui/buttons/callHistoryButton.png
service.gui.buttons.CALL_HISTORY_BUTTON_PRESSED=resources/images/impl/gui/buttons/callHistoryButtonPressed.png
@@ -262,8 +271,14 @@ service.gui.buttons.CALL_INFO=resources/images/impl/gui/buttons/callInfo.png
service.gui.buttons.ZRTP_ID_BUTTON=resources/images/impl/gui/buttons/zrtpEditId.png
# Sound level icons
-service.gui.soundlevel.SOUND_LEVEL_ACTIVE=resources/images/impl/gui/common/soundlevel/soundActive.png
-service.gui.soundlevel.SOUND_LEVEL_INACTIVE=resources/images/impl/gui/common/soundlevel/soundInactive.png
+service.gui.soundlevel.SOUND_LEVEL_ACTIVE_LEFT=resources/images/impl/gui/common/soundlevel/soundActiveLeft.png
+service.gui.soundlevel.SOUND_LEVEL_ACTIVE_LEFT_GRADIENT=resources/images/impl/gui/common/soundlevel/soundActiveLeftGradient.png
+service.gui.soundlevel.SOUND_LEVEL_ACTIVE_MIDDLE=resources/images/impl/gui/common/soundlevel/soundActiveMiddle.png
+service.gui.soundlevel.SOUND_LEVEL_ACTIVE_RIGHT=resources/images/impl/gui/common/soundlevel/soundActiveRight.png
+service.gui.soundlevel.SOUND_LEVEL_ACTIVE_RIGHT_GRADIENT=resources/images/impl/gui/common/soundlevel/soundActiveRightGradient.png
+service.gui.soundlevel.SOUND_LEVEL_INACTIVE_LEFT=resources/images/impl/gui/common/soundlevel/soundInactiveLeft.png
+service.gui.soundlevel.SOUND_LEVEL_INACTIVE_MIDDLE=resources/images/impl/gui/common/soundlevel/soundInactiveMiddle.png
+service.gui.soundlevel.SOUND_LEVEL_INACTIVE_RIGHT=resources/images/impl/gui/common/soundlevel/soundInactiveRight.png
service.gui.soundlevel.MICROPHONE=resources/images/impl/gui/common/soundlevel/Microphone.png
service.gui.soundlevel.HEADPHONE=resources/images/impl/gui/common/soundlevel/Headphone.png
service.gui.soundlevel.SOUND_SETTING_BUTTON_BG=resources/images/impl/gui/common/soundlevel/volumeButton.png
@@ -312,6 +327,18 @@ service.gui.lookandfeel.SCROLLBAR_HORIZONTAL=resources/images/impl/gui/lookandfe
service.gui.lookandfeel.SCROLLBAR_VERTICAL=resources/images/impl/gui/lookandfeel/scrollbar_vert1.png
service.gui.lookandfeel.SCROLLBAR_THUMB_HORIZONTAL=resources/images/impl/gui/lookandfeel/horizThumbHandle.png
service.gui.lookandfeel.SCROLLBAR_THUMB_VERTICAL=resources/images/impl/gui/lookandfeel/vertThumbHandle.png
+service.gui.lookandfeel.INCOMING_MESSAGE_BACKGROUND=resources/images/impl/gui/lookandfeel/yellowBackground.png
+service.gui.lookandfeel.INCOMING_MESSAGE_BACKGROUND_RIGHT=resources/images/impl/gui/lookandfeel/yellowBackgroundRight.png
+service.gui.lookandfeel.INCOMING_MESSAGE_INDICATOR=resources/images/impl/gui/lookandfeel/yellowIndicator.png
+service.gui.lookandfeel.INCOMING_MESSAGE_CURVES=resources/images/impl/gui/lookandfeel/yellowCurves.png
+service.gui.lookandfeel.INCOMING_MESSAGE_CURVES_TOP=resources/images/impl/gui/lookandfeel/yellowCurvesTop.png
+service.gui.lookandfeel.CHAT_MESSAGE_LINE=resources/images/impl/gui/lookandfeel/chatLine.png
+
+service.gui.lookandfeel.OUTGOING_MESSAGE_BACKGROUND=resources/images/impl/gui/lookandfeel/blueBackground.png
+service.gui.lookandfeel.OUTGOING_MESSAGE_BACKGROUND_RIGHT=resources/images/impl/gui/lookandfeel/blueBackgroundRight.png
+service.gui.lookandfeel.OUTGOING_MESSAGE_INDICATOR=resources/images/impl/gui/lookandfeel/blueIndicator.png
+service.gui.lookandfeel.OUTGOING_MESSAGE_CURVES=resources/images/impl/gui/lookandfeel/blueCurves.png
+service.gui.lookandfeel.OUTGOING_MESSAGE_CURVES_TOP=resources/images/impl/gui/lookandfeel/blueCurvesTop.png
service.gui.htmllookandfeel.PROGRESS_BAR_DEFAULT_BG=resources/images/impl/gui/common/bg_bar.gif
service.gui.htmllookandfeel.PROGRESS_BAR_BG=resources/images/impl/gui/common/bar.gif
diff --git a/resources/images/impl/gui/buttons/addAccount.png b/resources/images/impl/gui/buttons/addAccount.png
index 28b469c..faa2749 100644
--- a/resources/images/impl/gui/buttons/addAccount.png
+++ b/resources/images/impl/gui/buttons/addAccount.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/addAccountMenu.png b/resources/images/impl/gui/buttons/addAccountMenu.png
index b871a06..5f2838b 100644
--- a/resources/images/impl/gui/buttons/addAccountMenu.png
+++ b/resources/images/impl/gui/buttons/addAccountMenu.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/addContactSmall.png b/resources/images/impl/gui/buttons/addContactSmall.png
index 4c0bda7..46402c8 100644
--- a/resources/images/impl/gui/buttons/addContactSmall.png
+++ b/resources/images/impl/gui/buttons/addContactSmall.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/addContactSmallPressed.png b/resources/images/impl/gui/buttons/addContactSmallPressed.png
index 4bebb7e..774551d 100644
--- a/resources/images/impl/gui/buttons/addContactSmallPressed.png
+++ b/resources/images/impl/gui/buttons/addContactSmallPressed.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/addToCall.png b/resources/images/impl/gui/buttons/addToCall.png
index 5051da4..f9142d4 100644
--- a/resources/images/impl/gui/buttons/addToCall.png
+++ b/resources/images/impl/gui/buttons/addToCall.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/addToChat.png b/resources/images/impl/gui/buttons/addToChat.png
index 792d855..df52ce5 100644
--- a/resources/images/impl/gui/buttons/addToChat.png
+++ b/resources/images/impl/gui/buttons/addToChat.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/callButton.png b/resources/images/impl/gui/buttons/callButton.png
index 06c4a43..1b53155 100644
--- a/resources/images/impl/gui/buttons/callButton.png
+++ b/resources/images/impl/gui/buttons/callButton.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/callButtonPressed.png b/resources/images/impl/gui/buttons/callButtonPressed.png
index b45be01..16d864e 100644
--- a/resources/images/impl/gui/buttons/callButtonPressed.png
+++ b/resources/images/impl/gui/buttons/callButtonPressed.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/callDesktopSharing.png b/resources/images/impl/gui/buttons/callDesktopSharing.png
index e60c96f..0e1b2ec 100644
--- a/resources/images/impl/gui/buttons/callDesktopSharing.png
+++ b/resources/images/impl/gui/buttons/callDesktopSharing.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/callHistoryButton.png b/resources/images/impl/gui/buttons/callHistoryButton.png
index 78a9f38..e3473ff 100644
--- a/resources/images/impl/gui/buttons/callHistoryButton.png
+++ b/resources/images/impl/gui/buttons/callHistoryButton.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/callHistoryButtonPressed.png b/resources/images/impl/gui/buttons/callHistoryButtonPressed.png
index 4a123b4..310ea86 100644
--- a/resources/images/impl/gui/buttons/callHistoryButtonPressed.png
+++ b/resources/images/impl/gui/buttons/callHistoryButtonPressed.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/callInfo.png b/resources/images/impl/gui/buttons/callInfo.png
index 65a415b..fe67411 100644
--- a/resources/images/impl/gui/buttons/callInfo.png
+++ b/resources/images/impl/gui/buttons/callInfo.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/callSettingButton.png b/resources/images/impl/gui/buttons/callSettingButton.png
index 2cf63b6..117ec51 100644
--- a/resources/images/impl/gui/buttons/callSettingButton.png
+++ b/resources/images/impl/gui/buttons/callSettingButton.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/callSettingButtonPressed.png b/resources/images/impl/gui/buttons/callSettingButtonPressed.png
index bfdd0a1..f326c82 100644
--- a/resources/images/impl/gui/buttons/callSettingButtonPressed.png
+++ b/resources/images/impl/gui/buttons/callSettingButtonPressed.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/callSmall.png b/resources/images/impl/gui/buttons/callSmall.png
index 02b8e49..5cc20dc 100644
--- a/resources/images/impl/gui/buttons/callSmall.png
+++ b/resources/images/impl/gui/buttons/callSmall.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/callSmallPressed.png b/resources/images/impl/gui/buttons/callSmallPressed.png
index db8b820..8a32ec6 100644
--- a/resources/images/impl/gui/buttons/callSmallPressed.png
+++ b/resources/images/impl/gui/buttons/callSmallPressed.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/callVideoSmall.png b/resources/images/impl/gui/buttons/callVideoSmall.png
index 1c26046..15f4dc8 100644
--- a/resources/images/impl/gui/buttons/callVideoSmall.png
+++ b/resources/images/impl/gui/buttons/callVideoSmall.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/callVideoSmallPressed.png b/resources/images/impl/gui/buttons/callVideoSmallPressed.png
index f2f7169..74c4adc 100644
--- a/resources/images/impl/gui/buttons/callVideoSmallPressed.png
+++ b/resources/images/impl/gui/buttons/callVideoSmallPressed.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/chatCall.png b/resources/images/impl/gui/buttons/chatCall.png
index 9b4ee9e..ccaf918 100644
--- a/resources/images/impl/gui/buttons/chatCall.png
+++ b/resources/images/impl/gui/buttons/chatCall.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/chatDesktopSharing.png b/resources/images/impl/gui/buttons/chatDesktopSharing.png
index c22eb06..af0705c 100644
--- a/resources/images/impl/gui/buttons/chatDesktopSharing.png
+++ b/resources/images/impl/gui/buttons/chatDesktopSharing.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/chatRoomConfig.png b/resources/images/impl/gui/buttons/chatRoomConfig.png
index d9e4208..a17dd13 100644
--- a/resources/images/impl/gui/buttons/chatRoomConfig.png
+++ b/resources/images/impl/gui/buttons/chatRoomConfig.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/chatSmall.png b/resources/images/impl/gui/buttons/chatSmall.png
index b4a5637..37353c5 100644
--- a/resources/images/impl/gui/buttons/chatSmall.png
+++ b/resources/images/impl/gui/buttons/chatSmall.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/chatSmallPressed.png b/resources/images/impl/gui/buttons/chatSmallPressed.png
index 1a3c32e..99bac44 100644
--- a/resources/images/impl/gui/buttons/chatSmallPressed.png
+++ b/resources/images/impl/gui/buttons/chatSmallPressed.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/chatSmallWhite.png b/resources/images/impl/gui/buttons/chatSmallWhite.png
index 49b1a2d..f15f678 100644
--- a/resources/images/impl/gui/buttons/chatSmallWhite.png
+++ b/resources/images/impl/gui/buttons/chatSmallWhite.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/chatVideoCall.png b/resources/images/impl/gui/buttons/chatVideoCall.png
new file mode 100644
index 0000000..11e54ec
--- /dev/null
+++ b/resources/images/impl/gui/buttons/chatVideoCall.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/close.png b/resources/images/impl/gui/buttons/close.png
index 6fab7b7..47fba77 100644
--- a/resources/images/impl/gui/buttons/close.png
+++ b/resources/images/impl/gui/buttons/close.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/closeTab.png b/resources/images/impl/gui/buttons/closeTab.png
index d8bb99e..02e2c6a 100644
--- a/resources/images/impl/gui/buttons/closeTab.png
+++ b/resources/images/impl/gui/buttons/closeTab.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/contactListButtonBgLeft.png b/resources/images/impl/gui/buttons/contactListButtonBgLeft.png
new file mode 100644
index 0000000..966aac3
--- /dev/null
+++ b/resources/images/impl/gui/buttons/contactListButtonBgLeft.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/contactListButtonBgMiddle.png b/resources/images/impl/gui/buttons/contactListButtonBgMiddle.png
new file mode 100644
index 0000000..b61d69a
--- /dev/null
+++ b/resources/images/impl/gui/buttons/contactListButtonBgMiddle.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/contactListButtonBgRight.png b/resources/images/impl/gui/buttons/contactListButtonBgRight.png
new file mode 100644
index 0000000..716bd2d
--- /dev/null
+++ b/resources/images/impl/gui/buttons/contactListButtonBgRight.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/contactListButtonSeparator.png b/resources/images/impl/gui/buttons/contactListButtonSeparator.png
new file mode 100644
index 0000000..fa63cd5
--- /dev/null
+++ b/resources/images/impl/gui/buttons/contactListButtonSeparator.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/contactListDialButton.png b/resources/images/impl/gui/buttons/contactListDialButton.png
index 50bd8e0..3d8433e 100644
--- a/resources/images/impl/gui/buttons/contactListDialButton.png
+++ b/resources/images/impl/gui/buttons/contactListDialButton.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/contactListOneButtonBg.png b/resources/images/impl/gui/buttons/contactListOneButtonBg.png
new file mode 100644
index 0000000..8e5c2a7
--- /dev/null
+++ b/resources/images/impl/gui/buttons/contactListOneButtonBg.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/copy.png b/resources/images/impl/gui/buttons/copy.png
index 0670224..fc7d826 100644
--- a/resources/images/impl/gui/buttons/copy.png
+++ b/resources/images/impl/gui/buttons/copy.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/cut.png b/resources/images/impl/gui/buttons/cut.png
index 4aa43ef..d4f9203 100644
--- a/resources/images/impl/gui/buttons/cut.png
+++ b/resources/images/impl/gui/buttons/cut.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/desktopSharingSmall.png b/resources/images/impl/gui/buttons/desktopSharingSmall.png
index fab65c5..ec47587 100644
--- a/resources/images/impl/gui/buttons/desktopSharingSmall.png
+++ b/resources/images/impl/gui/buttons/desktopSharingSmall.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/desktopSharingSmallPressed.png b/resources/images/impl/gui/buttons/desktopSharingSmallPressed.png
index ff247ea..4d336c0 100644
--- a/resources/images/impl/gui/buttons/desktopSharingSmallPressed.png
+++ b/resources/images/impl/gui/buttons/desktopSharingSmallPressed.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/dialButton.png b/resources/images/impl/gui/buttons/dialButton.png
index 2e54171..48631fa 100644
--- a/resources/images/impl/gui/buttons/dialButton.png
+++ b/resources/images/impl/gui/buttons/dialButton.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/encrypted_verified.png b/resources/images/impl/gui/buttons/encrypted_verified.png
index c9fd25f..d5ba163 100755
--- a/resources/images/impl/gui/buttons/encrypted_verified.png
+++ b/resources/images/impl/gui/buttons/encrypted_verified.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/enterFullScreen.png b/resources/images/impl/gui/buttons/enterFullScreen.png
index f097103..9e932e6 100644
--- a/resources/images/impl/gui/buttons/enterFullScreen.png
+++ b/resources/images/impl/gui/buttons/enterFullScreen.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/exitFullScreen.png b/resources/images/impl/gui/buttons/exitFullScreen.png
index a01c051..502fff6 100644
--- a/resources/images/impl/gui/buttons/exitFullScreen.png
+++ b/resources/images/impl/gui/buttons/exitFullScreen.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/hangupButton.png b/resources/images/impl/gui/buttons/hangupButton.png
index 2741d54..430f47a 100644
--- a/resources/images/impl/gui/buttons/hangupButton.png
+++ b/resources/images/impl/gui/buttons/hangupButton.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/hangupButtonPressed.png b/resources/images/impl/gui/buttons/hangupButtonPressed.png
index 49eee1b..92bc68f 100644
--- a/resources/images/impl/gui/buttons/hangupButtonPressed.png
+++ b/resources/images/impl/gui/buttons/hangupButtonPressed.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/hdVideo.png b/resources/images/impl/gui/buttons/hdVideo.png
index c057d6e..e3175f3 100644
--- a/resources/images/impl/gui/buttons/hdVideo.png
+++ b/resources/images/impl/gui/buttons/hdVideo.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/history.png b/resources/images/impl/gui/buttons/history.png
index d76db0a..09cd2e4 100644
--- a/resources/images/impl/gui/buttons/history.png
+++ b/resources/images/impl/gui/buttons/history.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/holdButton.png b/resources/images/impl/gui/buttons/holdButton.png
index 41c56a2..570ea1b 100644
--- a/resources/images/impl/gui/buttons/holdButton.png
+++ b/resources/images/impl/gui/buttons/holdButton.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/holdButtonPressed.png b/resources/images/impl/gui/buttons/holdButtonPressed.png
index 9eff2d7..2727a75 100644
--- a/resources/images/impl/gui/buttons/holdButtonPressed.png
+++ b/resources/images/impl/gui/buttons/holdButtonPressed.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/infoIcon.png b/resources/images/impl/gui/buttons/infoIcon.png
index 48dc821..9a4c9a4 100644
--- a/resources/images/impl/gui/buttons/infoIcon.png
+++ b/resources/images/impl/gui/buttons/infoIcon.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/loVideo.png b/resources/images/impl/gui/buttons/loVideo.png
index 076b09d..22d37e4 100644
--- a/resources/images/impl/gui/buttons/loVideo.png
+++ b/resources/images/impl/gui/buttons/loVideo.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/localVideoButton.png b/resources/images/impl/gui/buttons/localVideoButton.png
index f2c7151..92b3bcf 100644
--- a/resources/images/impl/gui/buttons/localVideoButton.png
+++ b/resources/images/impl/gui/buttons/localVideoButton.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/localVideoButtonPressed.png b/resources/images/impl/gui/buttons/localVideoButtonPressed.png
index 69c35cd..03e0f39 100644
--- a/resources/images/impl/gui/buttons/localVideoButtonPressed.png
+++ b/resources/images/impl/gui/buttons/localVideoButtonPressed.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/muteButton.png b/resources/images/impl/gui/buttons/muteButton.png
index 5a08d72..0ffb0d0 100644
--- a/resources/images/impl/gui/buttons/muteButton.png
+++ b/resources/images/impl/gui/buttons/muteButton.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/muteButtonPressed.png b/resources/images/impl/gui/buttons/muteButtonPressed.png
index 852c010..420975f 100644
--- a/resources/images/impl/gui/buttons/muteButtonPressed.png
+++ b/resources/images/impl/gui/buttons/muteButtonPressed.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/next.png b/resources/images/impl/gui/buttons/next.png
index 1d610ff..d9d45ed 100644
--- a/resources/images/impl/gui/buttons/next.png
+++ b/resources/images/impl/gui/buttons/next.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/paste.png b/resources/images/impl/gui/buttons/paste.png
index 592d5f9..f2abed9 100644
--- a/resources/images/impl/gui/buttons/paste.png
+++ b/resources/images/impl/gui/buttons/paste.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/previous.png b/resources/images/impl/gui/buttons/previous.png
index 867bef5..f31868d 100644
--- a/resources/images/impl/gui/buttons/previous.png
+++ b/resources/images/impl/gui/buttons/previous.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/recordButton.png b/resources/images/impl/gui/buttons/recordButton.png
index 10931c4..4aaea30 100644
--- a/resources/images/impl/gui/buttons/recordButton.png
+++ b/resources/images/impl/gui/buttons/recordButton.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/recordButtonPressed.png b/resources/images/impl/gui/buttons/recordButtonPressed.png
index 4affa9b..58619b1 100644
--- a/resources/images/impl/gui/buttons/recordButtonPressed.png
+++ b/resources/images/impl/gui/buttons/recordButtonPressed.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/save.png b/resources/images/impl/gui/buttons/save.png
index 74008fa..3a91f95 100644
--- a/resources/images/impl/gui/buttons/save.png
+++ b/resources/images/impl/gui/buttons/save.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/sdVideo.png b/resources/images/impl/gui/buttons/sdVideo.png
index 27a6d5d..ca487e8 100644
--- a/resources/images/impl/gui/buttons/sdVideo.png
+++ b/resources/images/impl/gui/buttons/sdVideo.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/searchCallIcon.png b/resources/images/impl/gui/buttons/searchCallIcon.png
index 4c50ecb..a751929 100644
--- a/resources/images/impl/gui/buttons/searchCallIcon.png
+++ b/resources/images/impl/gui/buttons/searchCallIcon.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/searchCallRolloverIcon.png b/resources/images/impl/gui/buttons/searchCallRolloverIcon.png
index 46cee5a..79add6c 100644
--- a/resources/images/impl/gui/buttons/searchCallRolloverIcon.png
+++ b/resources/images/impl/gui/buttons/searchCallRolloverIcon.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/secureAudioOff.png b/resources/images/impl/gui/buttons/secureAudioOff.png
index d32800c..201e782 100644
--- a/resources/images/impl/gui/buttons/secureAudioOff.png
+++ b/resources/images/impl/gui/buttons/secureAudioOff.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/secureAudioOn.png b/resources/images/impl/gui/buttons/secureAudioOn.png
index c408c4f..7bbbb51 100644
--- a/resources/images/impl/gui/buttons/secureAudioOn.png
+++ b/resources/images/impl/gui/buttons/secureAudioOn.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/secureVideoOff.png b/resources/images/impl/gui/buttons/secureVideoOff.png
index d4d144b..546aaad 100644
--- a/resources/images/impl/gui/buttons/secureVideoOff.png
+++ b/resources/images/impl/gui/buttons/secureVideoOff.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/secureVideoOn.png b/resources/images/impl/gui/buttons/secureVideoOn.png
index 4f020a6..489784b 100644
--- a/resources/images/impl/gui/buttons/secureVideoOn.png
+++ b/resources/images/impl/gui/buttons/secureVideoOn.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/sendFile.png b/resources/images/impl/gui/buttons/sendFile.png
index e8c40d9..bd08bd4 100644
--- a/resources/images/impl/gui/buttons/sendFile.png
+++ b/resources/images/impl/gui/buttons/sendFile.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/showHideLocalVideo.png b/resources/images/impl/gui/buttons/showHideLocalVideo.png
index 60ad55d..dc1f4b9 100644
--- a/resources/images/impl/gui/buttons/showHideLocalVideo.png
+++ b/resources/images/impl/gui/buttons/showHideLocalVideo.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/showHideLocalVideoPressed.png b/resources/images/impl/gui/buttons/showHideLocalVideoPressed.png
index 3a4d6ec..036a0f7 100644
--- a/resources/images/impl/gui/buttons/showHideLocalVideoPressed.png
+++ b/resources/images/impl/gui/buttons/showHideLocalVideoPressed.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/smiley.png b/resources/images/impl/gui/buttons/smiley.png
index b16f700..fb7d838 100644
--- a/resources/images/impl/gui/buttons/smiley.png
+++ b/resources/images/impl/gui/buttons/smiley.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/transferCallButton.png b/resources/images/impl/gui/buttons/transferCallButton.png
index 2367d46..1b5b563 100644
--- a/resources/images/impl/gui/buttons/transferCallButton.png
+++ b/resources/images/impl/gui/buttons/transferCallButton.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/videoCallButton.png b/resources/images/impl/gui/buttons/videoCallButton.png
index ba49233..e6fa719 100644
--- a/resources/images/impl/gui/buttons/videoCallButton.png
+++ b/resources/images/impl/gui/buttons/videoCallButton.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/videoCallButtonPressed.png b/resources/images/impl/gui/buttons/videoCallButtonPressed.png
index 9fe4f79..681f02d 100644
--- a/resources/images/impl/gui/buttons/videoCallButtonPressed.png
+++ b/resources/images/impl/gui/buttons/videoCallButtonPressed.png
Binary files differ
diff --git a/resources/images/impl/gui/buttons/volumeControl.png b/resources/images/impl/gui/buttons/volumeControl.png
index 8b2e214..aa0180a 100644
--- a/resources/images/impl/gui/buttons/volumeControl.png
+++ b/resources/images/impl/gui/buttons/volumeControl.png
Binary files differ
diff --git a/resources/images/impl/gui/common/addContact16x16.png b/resources/images/impl/gui/common/addContact16x16.png
index d619450..c59031f 100644
--- a/resources/images/impl/gui/common/addContact16x16.png
+++ b/resources/images/impl/gui/common/addContact16x16.png
Binary files differ
diff --git a/resources/images/impl/gui/common/addContactDialogIcon.png b/resources/images/impl/gui/common/addContactDialogIcon.png
index bd9b284..5b1f4ed 100644
--- a/resources/images/impl/gui/common/addContactDialogIcon.png
+++ b/resources/images/impl/gui/common/addContactDialogIcon.png
Binary files differ
diff --git a/resources/images/impl/gui/common/addGroup.png b/resources/images/impl/gui/common/addGroup.png
index c9219fc..2872b7e 100644
--- a/resources/images/impl/gui/common/addGroup.png
+++ b/resources/images/impl/gui/common/addGroup.png
Binary files differ
diff --git a/resources/images/impl/gui/common/admin.png b/resources/images/impl/gui/common/admin.png
index 09ef180..030dc0b 100644
--- a/resources/images/impl/gui/common/admin.png
+++ b/resources/images/impl/gui/common/admin.png
Binary files differ
diff --git a/resources/images/impl/gui/common/browser16x16.png b/resources/images/impl/gui/common/browser16x16.png
index 302b0fd..b5ffc2d 100644
--- a/resources/images/impl/gui/common/browser16x16.png
+++ b/resources/images/impl/gui/common/browser16x16.png
Binary files differ
diff --git a/resources/images/impl/gui/common/call16x16.png b/resources/images/impl/gui/common/call16x16.png
index b1482f7..e237e5a 100644
--- a/resources/images/impl/gui/common/call16x16.png
+++ b/resources/images/impl/gui/common/call16x16.png
Binary files differ
diff --git a/resources/images/impl/gui/common/callHistoryButtonNotification.png b/resources/images/impl/gui/common/callHistoryButtonNotification.png
new file mode 100644
index 0000000..b6f29f8
--- /dev/null
+++ b/resources/images/impl/gui/common/callHistoryButtonNotification.png
Binary files differ
diff --git a/resources/images/impl/gui/common/callToolbarSeparator.png b/resources/images/impl/gui/common/callToolbarSeparator.png
new file mode 100644
index 0000000..268140d
--- /dev/null
+++ b/resources/images/impl/gui/common/callToolbarSeparator.png
Binary files differ
diff --git a/resources/images/impl/gui/common/changeNickname16x16.png b/resources/images/impl/gui/common/changeNickname16x16.png
index 4a1befe..cf7c9f1 100644
--- a/resources/images/impl/gui/common/changeNickname16x16.png
+++ b/resources/images/impl/gui/common/changeNickname16x16.png
Binary files differ
diff --git a/resources/images/impl/gui/common/changeSubject16x16.png b/resources/images/impl/gui/common/changeSubject16x16.png
index eafc565..573258c 100644
--- a/resources/images/impl/gui/common/changeSubject16x16.png
+++ b/resources/images/impl/gui/common/changeSubject16x16.png
Binary files differ
diff --git a/resources/images/impl/gui/common/chatRoom16x16.png b/resources/images/impl/gui/common/chatRoom16x16.png
index 2bbc423..f07f516 100644
--- a/resources/images/impl/gui/common/chatRoom16x16.png
+++ b/resources/images/impl/gui/common/chatRoom16x16.png
Binary files differ
diff --git a/resources/images/impl/gui/common/closedGroup.png b/resources/images/impl/gui/common/closedGroup.png
index 8535092..999b85f 100644
--- a/resources/images/impl/gui/common/closedGroup.png
+++ b/resources/images/impl/gui/common/closedGroup.png
Binary files differ
diff --git a/resources/images/impl/gui/common/delete16x16.png b/resources/images/impl/gui/common/delete16x16.png
index 8086c8b..87a3d2a 100644
--- a/resources/images/impl/gui/common/delete16x16.png
+++ b/resources/images/impl/gui/common/delete16x16.png
Binary files differ
diff --git a/resources/images/impl/gui/common/desktopSharing16x16.png b/resources/images/impl/gui/common/desktopSharing16x16.png
index ca336dd..9a03709 100644
--- a/resources/images/impl/gui/common/desktopSharing16x16.png
+++ b/resources/images/impl/gui/common/desktopSharing16x16.png
Binary files differ
diff --git a/resources/images/impl/gui/common/downArrow.png b/resources/images/impl/gui/common/downArrow.png
index fc78bb0..3ba9bc2 100644
--- a/resources/images/impl/gui/common/downArrow.png
+++ b/resources/images/impl/gui/common/downArrow.png
Binary files differ
diff --git a/resources/images/impl/gui/common/envelope.png b/resources/images/impl/gui/common/envelope.png
index be012e9..ce802a5 100644
--- a/resources/images/impl/gui/common/envelope.png
+++ b/resources/images/impl/gui/common/envelope.png
Binary files differ
diff --git a/resources/images/impl/gui/common/groups16x16.png b/resources/images/impl/gui/common/groups16x16.png
index c35dd64..8c33c98 100644
--- a/resources/images/impl/gui/common/groups16x16.png
+++ b/resources/images/impl/gui/common/groups16x16.png
Binary files differ
diff --git a/resources/images/impl/gui/common/hdVideo.png b/resources/images/impl/gui/common/hdVideo.png
new file mode 100644
index 0000000..e3175f3
--- /dev/null
+++ b/resources/images/impl/gui/common/hdVideo.png
Binary files differ
diff --git a/resources/images/impl/gui/common/history16x16.png b/resources/images/impl/gui/common/history16x16.png
index 67ba572..30e70fe 100644
--- a/resources/images/impl/gui/common/history16x16.png
+++ b/resources/images/impl/gui/common/history16x16.png
Binary files differ
diff --git a/resources/images/impl/gui/common/incomingCall.png b/resources/images/impl/gui/common/incomingCall.png
index bbcc12c..993bfca 100644
--- a/resources/images/impl/gui/common/incomingCall.png
+++ b/resources/images/impl/gui/common/incomingCall.png
Binary files differ
diff --git a/resources/images/impl/gui/common/incomingCallBgLeft.png b/resources/images/impl/gui/common/incomingCallBgLeft.png
new file mode 100644
index 0000000..494621c
--- /dev/null
+++ b/resources/images/impl/gui/common/incomingCallBgLeft.png
Binary files differ
diff --git a/resources/images/impl/gui/common/incomingCallBgMiddle.png b/resources/images/impl/gui/common/incomingCallBgMiddle.png
new file mode 100644
index 0000000..5cfd842
--- /dev/null
+++ b/resources/images/impl/gui/common/incomingCallBgMiddle.png
Binary files differ
diff --git a/resources/images/impl/gui/common/incomingCallBgRight.png b/resources/images/impl/gui/common/incomingCallBgRight.png
new file mode 100644
index 0000000..b37d5dc
--- /dev/null
+++ b/resources/images/impl/gui/common/incomingCallBgRight.png
Binary files differ
diff --git a/resources/images/impl/gui/common/leave.png b/resources/images/impl/gui/common/leave.png
index 6778929..5fff3ed 100644
--- a/resources/images/impl/gui/common/leave.png
+++ b/resources/images/impl/gui/common/leave.png
Binary files differ
diff --git a/resources/images/impl/gui/common/leaveold.png b/resources/images/impl/gui/common/leaveold.png
new file mode 100644
index 0000000..a61219d
--- /dev/null
+++ b/resources/images/impl/gui/common/leaveold.png
Binary files differ
diff --git a/resources/images/impl/gui/common/loVideo.png b/resources/images/impl/gui/common/loVideo.png
new file mode 100644
index 0000000..22d37e4
--- /dev/null
+++ b/resources/images/impl/gui/common/loVideo.png
Binary files differ
diff --git a/resources/images/impl/gui/common/missedCall.png b/resources/images/impl/gui/common/missedCall.png
index 5bc2e96..6502180 100644
--- a/resources/images/impl/gui/common/missedCall.png
+++ b/resources/images/impl/gui/common/missedCall.png
Binary files differ
diff --git a/resources/images/impl/gui/common/moderator.png b/resources/images/impl/gui/common/moderator.png
index d36008c..9a8376d 100644
--- a/resources/images/impl/gui/common/moderator.png
+++ b/resources/images/impl/gui/common/moderator.png
Binary files differ
diff --git a/resources/images/impl/gui/common/moveContact.png b/resources/images/impl/gui/common/moveContact.png
index cd14c74..05cfc6f 100644
--- a/resources/images/impl/gui/common/moveContact.png
+++ b/resources/images/impl/gui/common/moveContact.png
Binary files differ
diff --git a/resources/images/impl/gui/common/moveToGroup16x16.png b/resources/images/impl/gui/common/moveToGroup16x16.png
index 28166d8..1746a12 100644
--- a/resources/images/impl/gui/common/moveToGroup16x16.png
+++ b/resources/images/impl/gui/common/moveToGroup16x16.png
Binary files differ
diff --git a/resources/images/impl/gui/common/noSound.png b/resources/images/impl/gui/common/noSound.png
new file mode 100644
index 0000000..593ea23
--- /dev/null
+++ b/resources/images/impl/gui/common/noSound.png
Binary files differ
diff --git a/resources/images/impl/gui/common/openedGroup.png b/resources/images/impl/gui/common/openedGroup.png
index cc7bda3..37bec6a 100644
--- a/resources/images/impl/gui/common/openedGroup.png
+++ b/resources/images/impl/gui/common/openedGroup.png
Binary files differ
diff --git a/resources/images/impl/gui/common/outgoingCall.png b/resources/images/impl/gui/common/outgoingCall.png
index 849fec4..f780a8a 100644
--- a/resources/images/impl/gui/common/outgoingCall.png
+++ b/resources/images/impl/gui/common/outgoingCall.png
Binary files differ
diff --git a/resources/images/impl/gui/common/owner.png b/resources/images/impl/gui/common/owner.png
index 2e7d0c3..585624e 100644
--- a/resources/images/impl/gui/common/owner.png
+++ b/resources/images/impl/gui/common/owner.png
Binary files differ
diff --git a/resources/images/impl/gui/common/padlock.png b/resources/images/impl/gui/common/padlock.png
index 9c91c6d..9c9762b 100644
--- a/resources/images/impl/gui/common/padlock.png
+++ b/resources/images/impl/gui/common/padlock.png
Binary files differ
diff --git a/resources/images/impl/gui/common/personPhoto.png b/resources/images/impl/gui/common/personPhoto.png
index 37b38f1..c2b04bd 100644
--- a/resources/images/impl/gui/common/personPhoto.png
+++ b/resources/images/impl/gui/common/personPhoto.png
Binary files differ
diff --git a/resources/images/impl/gui/common/personPhotoFrame.png b/resources/images/impl/gui/common/personPhotoFrame.png
index 265289d..fe9fcb5 100644
--- a/resources/images/impl/gui/common/personPhotoFrame.png
+++ b/resources/images/impl/gui/common/personPhotoFrame.png
Binary files differ
diff --git a/resources/images/impl/gui/common/personPhotoSmall.png b/resources/images/impl/gui/common/personPhotoSmall.png
new file mode 100644
index 0000000..0fcffe3
--- /dev/null
+++ b/resources/images/impl/gui/common/personPhotoSmall.png
Binary files differ
diff --git a/resources/images/impl/gui/common/regionSharing16x16.png b/resources/images/impl/gui/common/regionSharing16x16.png
index 0aeb0d9..c6255f6 100644
--- a/resources/images/impl/gui/common/regionSharing16x16.png
+++ b/resources/images/impl/gui/common/regionSharing16x16.png
Binary files differ
diff --git a/resources/images/impl/gui/common/rename16x16.png b/resources/images/impl/gui/common/rename16x16.png
index b18cc5a..c70be01 100644
--- a/resources/images/impl/gui/common/rename16x16.png
+++ b/resources/images/impl/gui/common/rename16x16.png
Binary files differ
diff --git a/resources/images/impl/gui/common/renameDialogIcon.png b/resources/images/impl/gui/common/renameDialogIcon.png
index 7de974e..56f5964 100644
--- a/resources/images/impl/gui/common/renameDialogIcon.png
+++ b/resources/images/impl/gui/common/renameDialogIcon.png
Binary files differ
diff --git a/resources/images/impl/gui/common/searchIcon.png b/resources/images/impl/gui/common/searchIcon.png
index d81f019..5d635cd 100644
--- a/resources/images/impl/gui/common/searchIcon.png
+++ b/resources/images/impl/gui/common/searchIcon.png
Binary files differ
diff --git a/resources/images/impl/gui/common/sendFile16x16.png b/resources/images/impl/gui/common/sendFile16x16.png
index 0b3a15d..8da89a6 100644
--- a/resources/images/impl/gui/common/sendFile16x16.png
+++ b/resources/images/impl/gui/common/sendFile16x16.png
Binary files differ
diff --git a/resources/images/impl/gui/common/sendMessage16x16.png b/resources/images/impl/gui/common/sendMessage16x16.png
index 753b06f..9f2970d 100644
--- a/resources/images/impl/gui/common/sendMessage16x16.png
+++ b/resources/images/impl/gui/common/sendMessage16x16.png
Binary files differ
diff --git a/resources/images/impl/gui/common/separator.png b/resources/images/impl/gui/common/separator.png
new file mode 100644
index 0000000..8b9fa7d
--- /dev/null
+++ b/resources/images/impl/gui/common/separator.png
Binary files differ
diff --git a/resources/images/impl/gui/common/showHideOffline.png b/resources/images/impl/gui/common/showHideOffline.png
index d413945..c98bfe6 100644
--- a/resources/images/impl/gui/common/showHideOffline.png
+++ b/resources/images/impl/gui/common/showHideOffline.png
Binary files differ
diff --git a/resources/images/impl/gui/common/silent.png b/resources/images/impl/gui/common/silent.png
index b1ddbbf..6772019 100644
--- a/resources/images/impl/gui/common/silent.png
+++ b/resources/images/impl/gui/common/silent.png
Binary files differ
diff --git a/resources/images/impl/gui/common/soundMenu.png b/resources/images/impl/gui/common/soundMenu.png
index dc7c68d..ef19938 100644
--- a/resources/images/impl/gui/common/soundMenu.png
+++ b/resources/images/impl/gui/common/soundMenu.png
Binary files differ
diff --git a/resources/images/impl/gui/common/soundlevel/Headphone.png b/resources/images/impl/gui/common/soundlevel/Headphone.png
index b6459b7..27d343e 100644
--- a/resources/images/impl/gui/common/soundlevel/Headphone.png
+++ b/resources/images/impl/gui/common/soundlevel/Headphone.png
Binary files differ
diff --git a/resources/images/impl/gui/common/soundlevel/Microphone.png b/resources/images/impl/gui/common/soundlevel/Microphone.png
index 835354a..24b55aa 100644
--- a/resources/images/impl/gui/common/soundlevel/Microphone.png
+++ b/resources/images/impl/gui/common/soundlevel/Microphone.png
Binary files differ
diff --git a/resources/images/impl/gui/common/soundlevel/soundActiveLeft.png b/resources/images/impl/gui/common/soundlevel/soundActiveLeft.png
new file mode 100644
index 0000000..01f4d90
--- /dev/null
+++ b/resources/images/impl/gui/common/soundlevel/soundActiveLeft.png
Binary files differ
diff --git a/resources/images/impl/gui/common/soundlevel/soundActiveLeftGradient.png b/resources/images/impl/gui/common/soundlevel/soundActiveLeftGradient.png
new file mode 100644
index 0000000..8811717
--- /dev/null
+++ b/resources/images/impl/gui/common/soundlevel/soundActiveLeftGradient.png
Binary files differ
diff --git a/resources/images/impl/gui/common/soundlevel/soundActiveMiddle.png b/resources/images/impl/gui/common/soundlevel/soundActiveMiddle.png
new file mode 100644
index 0000000..0ae6202
--- /dev/null
+++ b/resources/images/impl/gui/common/soundlevel/soundActiveMiddle.png
Binary files differ
diff --git a/resources/images/impl/gui/common/soundlevel/soundActiveRight.png b/resources/images/impl/gui/common/soundlevel/soundActiveRight.png
new file mode 100644
index 0000000..f1ba8de
--- /dev/null
+++ b/resources/images/impl/gui/common/soundlevel/soundActiveRight.png
Binary files differ
diff --git a/resources/images/impl/gui/common/soundlevel/soundActiveRightGradient.png b/resources/images/impl/gui/common/soundlevel/soundActiveRightGradient.png
new file mode 100644
index 0000000..d32046b
--- /dev/null
+++ b/resources/images/impl/gui/common/soundlevel/soundActiveRightGradient.png
Binary files differ
diff --git a/resources/images/impl/gui/common/soundlevel/soundInactiveLeft.png b/resources/images/impl/gui/common/soundlevel/soundInactiveLeft.png
new file mode 100644
index 0000000..07adc08
--- /dev/null
+++ b/resources/images/impl/gui/common/soundlevel/soundInactiveLeft.png
Binary files differ
diff --git a/resources/images/impl/gui/common/soundlevel/soundInactiveMiddle.png b/resources/images/impl/gui/common/soundlevel/soundInactiveMiddle.png
new file mode 100644
index 0000000..ea879f4
--- /dev/null
+++ b/resources/images/impl/gui/common/soundlevel/soundInactiveMiddle.png
Binary files differ
diff --git a/resources/images/impl/gui/common/soundlevel/soundInactiveRight.png b/resources/images/impl/gui/common/soundlevel/soundInactiveRight.png
new file mode 100644
index 0000000..e23d807
--- /dev/null
+++ b/resources/images/impl/gui/common/soundlevel/soundInactiveRight.png
Binary files differ
diff --git a/resources/images/impl/gui/common/soundlevel/volumeButton.png b/resources/images/impl/gui/common/soundlevel/volumeButton.png
index ed49c24..dd6302a 100644
--- a/resources/images/impl/gui/common/soundlevel/volumeButton.png
+++ b/resources/images/impl/gui/common/soundlevel/volumeButton.png
Binary files differ
diff --git a/resources/images/impl/gui/common/soundlevel/volumeButtonPressed.png b/resources/images/impl/gui/common/soundlevel/volumeButtonPressed.png
index 4b91193..c75fe5a 100644
--- a/resources/images/impl/gui/common/soundlevel/volumeButtonPressed.png
+++ b/resources/images/impl/gui/common/soundlevel/volumeButtonPressed.png
Binary files differ
diff --git a/resources/images/impl/gui/common/standard.png b/resources/images/impl/gui/common/standard.png
index 5135bac..2765b0f 100644
--- a/resources/images/impl/gui/common/standard.png
+++ b/resources/images/impl/gui/common/standard.png
Binary files differ
diff --git a/resources/images/impl/gui/common/statusicons/away.png b/resources/images/impl/gui/common/statusicons/away.png
index dda2596..bf4747e 100644
--- a/resources/images/impl/gui/common/statusicons/away.png
+++ b/resources/images/impl/gui/common/statusicons/away.png
Binary files differ
diff --git a/resources/images/impl/gui/common/statusicons/dnd.png b/resources/images/impl/gui/common/statusicons/dnd.png
index 1e24bc9..7f47cd2 100644
--- a/resources/images/impl/gui/common/statusicons/dnd.png
+++ b/resources/images/impl/gui/common/statusicons/dnd.png
Binary files differ
diff --git a/resources/images/impl/gui/common/statusicons/freeForChat.png b/resources/images/impl/gui/common/statusicons/freeForChat.png
index 41365b2..2b68e71 100644
--- a/resources/images/impl/gui/common/statusicons/freeForChat.png
+++ b/resources/images/impl/gui/common/statusicons/freeForChat.png
Binary files differ
diff --git a/resources/images/impl/gui/common/statusicons/offline.png b/resources/images/impl/gui/common/statusicons/offline.png
index 2138388..7832614 100644
--- a/resources/images/impl/gui/common/statusicons/offline.png
+++ b/resources/images/impl/gui/common/statusicons/offline.png
Binary files differ
diff --git a/resources/images/impl/gui/common/statusicons/online.png b/resources/images/impl/gui/common/statusicons/online.png
index 1526708..3ad0e6a 100644
--- a/resources/images/impl/gui/common/statusicons/online.png
+++ b/resources/images/impl/gui/common/statusicons/online.png
Binary files differ
diff --git a/resources/images/impl/gui/common/unauthorizedContact16x16.png b/resources/images/impl/gui/common/unauthorizedContact16x16.png
index aedaf0e..333e5f0 100644
--- a/resources/images/impl/gui/common/unauthorizedContact16x16.png
+++ b/resources/images/impl/gui/common/unauthorizedContact16x16.png
Binary files differ
diff --git a/resources/images/impl/gui/common/videoCall16x16.png b/resources/images/impl/gui/common/videoCall16x16.png
index 39d82d5..5571785 100644
--- a/resources/images/impl/gui/common/videoCall16x16.png
+++ b/resources/images/impl/gui/common/videoCall16x16.png
Binary files differ
diff --git a/resources/images/impl/gui/common/voicemail.png b/resources/images/impl/gui/common/voicemail.png
index 737c73b..e6445b0 100644
--- a/resources/images/impl/gui/common/voicemail.png
+++ b/resources/images/impl/gui/common/voicemail.png
Binary files differ
diff --git a/resources/images/impl/gui/lookandfeel/blueBackground.png b/resources/images/impl/gui/lookandfeel/blueBackground.png
new file mode 100644
index 0000000..5e7f771
--- /dev/null
+++ b/resources/images/impl/gui/lookandfeel/blueBackground.png
Binary files differ
diff --git a/resources/images/impl/gui/lookandfeel/blueBackgroundRight.png b/resources/images/impl/gui/lookandfeel/blueBackgroundRight.png
new file mode 100644
index 0000000..56d39b6
--- /dev/null
+++ b/resources/images/impl/gui/lookandfeel/blueBackgroundRight.png
Binary files differ
diff --git a/resources/images/impl/gui/lookandfeel/blueCurves.png b/resources/images/impl/gui/lookandfeel/blueCurves.png
new file mode 100644
index 0000000..5fc7185
--- /dev/null
+++ b/resources/images/impl/gui/lookandfeel/blueCurves.png
Binary files differ
diff --git a/resources/images/impl/gui/lookandfeel/blueCurvesTop.png b/resources/images/impl/gui/lookandfeel/blueCurvesTop.png
new file mode 100644
index 0000000..db6cad3
--- /dev/null
+++ b/resources/images/impl/gui/lookandfeel/blueCurvesTop.png
Binary files differ
diff --git a/resources/images/impl/gui/lookandfeel/blueIndicator.png b/resources/images/impl/gui/lookandfeel/blueIndicator.png
new file mode 100644
index 0000000..23fe03f
--- /dev/null
+++ b/resources/images/impl/gui/lookandfeel/blueIndicator.png
Binary files differ
diff --git a/resources/images/impl/gui/lookandfeel/box-bg.png b/resources/images/impl/gui/lookandfeel/box-bg.png
new file mode 100755
index 0000000..48baa54
--- /dev/null
+++ b/resources/images/impl/gui/lookandfeel/box-bg.png
Binary files differ
diff --git a/resources/images/impl/gui/lookandfeel/chatLine.png b/resources/images/impl/gui/lookandfeel/chatLine.png
new file mode 100644
index 0000000..25dec1d
--- /dev/null
+++ b/resources/images/impl/gui/lookandfeel/chatLine.png
Binary files differ
diff --git a/resources/images/impl/gui/lookandfeel/selectedTabLeft.png b/resources/images/impl/gui/lookandfeel/selectedTabLeft.png
index bb426c7..10d3141 100644
--- a/resources/images/impl/gui/lookandfeel/selectedTabLeft.png
+++ b/resources/images/impl/gui/lookandfeel/selectedTabLeft.png
Binary files differ
diff --git a/resources/images/impl/gui/lookandfeel/selectedTabMiddle.png b/resources/images/impl/gui/lookandfeel/selectedTabMiddle.png
index 3364e9d..3b31cab 100644
--- a/resources/images/impl/gui/lookandfeel/selectedTabMiddle.png
+++ b/resources/images/impl/gui/lookandfeel/selectedTabMiddle.png
Binary files differ
diff --git a/resources/images/impl/gui/lookandfeel/selectedTabRight.png b/resources/images/impl/gui/lookandfeel/selectedTabRight.png
index 5474d78..e2e78ac 100644
--- a/resources/images/impl/gui/lookandfeel/selectedTabRight.png
+++ b/resources/images/impl/gui/lookandfeel/selectedTabRight.png
Binary files differ
diff --git a/resources/images/impl/gui/lookandfeel/tabLeft.png b/resources/images/impl/gui/lookandfeel/tabLeft.png
index c8e32f8..9da0027 100644
--- a/resources/images/impl/gui/lookandfeel/tabLeft.png
+++ b/resources/images/impl/gui/lookandfeel/tabLeft.png
Binary files differ
diff --git a/resources/images/impl/gui/lookandfeel/tabMiddle.png b/resources/images/impl/gui/lookandfeel/tabMiddle.png
index 93b1418..c6a357a 100644
--- a/resources/images/impl/gui/lookandfeel/tabMiddle.png
+++ b/resources/images/impl/gui/lookandfeel/tabMiddle.png
Binary files differ
diff --git a/resources/images/impl/gui/lookandfeel/tabRight.png b/resources/images/impl/gui/lookandfeel/tabRight.png
index 4d70679..57802f8 100644
--- a/resources/images/impl/gui/lookandfeel/tabRight.png
+++ b/resources/images/impl/gui/lookandfeel/tabRight.png
Binary files differ
diff --git a/resources/images/impl/gui/lookandfeel/yellowBackground.png b/resources/images/impl/gui/lookandfeel/yellowBackground.png
new file mode 100644
index 0000000..5e7f771
--- /dev/null
+++ b/resources/images/impl/gui/lookandfeel/yellowBackground.png
Binary files differ
diff --git a/resources/images/impl/gui/lookandfeel/yellowBackgroundRight.png b/resources/images/impl/gui/lookandfeel/yellowBackgroundRight.png
new file mode 100644
index 0000000..56d39b6
--- /dev/null
+++ b/resources/images/impl/gui/lookandfeel/yellowBackgroundRight.png
Binary files differ
diff --git a/resources/images/impl/gui/lookandfeel/yellowCurves.png b/resources/images/impl/gui/lookandfeel/yellowCurves.png
new file mode 100644
index 0000000..5fc7185
--- /dev/null
+++ b/resources/images/impl/gui/lookandfeel/yellowCurves.png
Binary files differ
diff --git a/resources/images/impl/gui/lookandfeel/yellowCurvesTop.png b/resources/images/impl/gui/lookandfeel/yellowCurvesTop.png
new file mode 100644
index 0000000..db6cad3
--- /dev/null
+++ b/resources/images/impl/gui/lookandfeel/yellowCurvesTop.png
Binary files differ
diff --git a/resources/images/impl/gui/lookandfeel/yellowIndicator.png b/resources/images/impl/gui/lookandfeel/yellowIndicator.png
new file mode 100644
index 0000000..96d2fd9
--- /dev/null
+++ b/resources/images/impl/gui/lookandfeel/yellowIndicator.png
Binary files differ
diff --git a/resources/images/impl/media/audioConfig.png b/resources/images/impl/media/audioConfig.png
index 79f1a27..3eec96c 100644
--- a/resources/images/impl/media/audioConfig.png
+++ b/resources/images/impl/media/audioConfig.png
Binary files differ
diff --git a/resources/images/impl/media/videoConfig.png b/resources/images/impl/media/videoConfig.png
index 750e7b7..287ab1d 100644
--- a/resources/images/impl/media/videoConfig.png
+++ b/resources/images/impl/media/videoConfig.png
Binary files differ
diff --git a/resources/images/impl/systray/dock-away.png b/resources/images/impl/systray/dock-away.png
index a79a2aa..febe9d1 100644
--- a/resources/images/impl/systray/dock-away.png
+++ b/resources/images/impl/systray/dock-away.png
Binary files differ
diff --git a/resources/images/impl/systray/dock-chatty.png b/resources/images/impl/systray/dock-chatty.png
index a4f87e2..c7b9334 100644
--- a/resources/images/impl/systray/dock-chatty.png
+++ b/resources/images/impl/systray/dock-chatty.png
Binary files differ
diff --git a/resources/images/impl/systray/dock-dnd.png b/resources/images/impl/systray/dock-dnd.png
index 4ac6cb2..d0a1446 100644
--- a/resources/images/impl/systray/dock-dnd.png
+++ b/resources/images/impl/systray/dock-dnd.png
Binary files differ
diff --git a/resources/images/impl/systray/dock-offline.png b/resources/images/impl/systray/dock-offline.png
index 3af41a9..f3eeec2 100644
--- a/resources/images/impl/systray/dock-offline.png
+++ b/resources/images/impl/systray/dock-offline.png
Binary files differ
diff --git a/resources/images/impl/systray/dock-online.png b/resources/images/impl/systray/dock-online.png
index 086912d..41dd760 100644
--- a/resources/images/impl/systray/dock-online.png
+++ b/resources/images/impl/systray/dock-online.png
Binary files differ
diff --git a/resources/images/impl/systray/envelope.png b/resources/images/impl/systray/envelope.png
index 08dc32a..04ffbf7 100644
--- a/resources/images/impl/systray/envelope.png
+++ b/resources/images/impl/systray/envelope.png
Binary files differ
diff --git a/resources/images/impl/systray/envelopeMacOSX.png b/resources/images/impl/systray/envelopeMacOSX.png
index 916cfcd..f107507 100644
--- a/resources/images/impl/systray/envelopeMacOSX.png
+++ b/resources/images/impl/systray/envelopeMacOSX.png
Binary files differ
diff --git a/resources/images/impl/systray/envelopeMacOSXWhite.png b/resources/images/impl/systray/envelopeMacOSXWhite.png
index 202b269..a6a9b1d 100644
--- a/resources/images/impl/systray/envelopeMacOSXWhite.png
+++ b/resources/images/impl/systray/envelopeMacOSXWhite.png
Binary files differ
diff --git a/resources/images/impl/systray/envelopeWindows.png b/resources/images/impl/systray/envelopeWindows.png
index b3f5de5..da200b1 100644
--- a/resources/images/impl/systray/envelopeWindows.png
+++ b/resources/images/impl/systray/envelopeWindows.png
Binary files differ
diff --git a/resources/images/impl/systray/systrayIcon.png b/resources/images/impl/systray/systrayIcon.png
index 85bc142..7f50214 100644
--- a/resources/images/impl/systray/systrayIcon.png
+++ b/resources/images/impl/systray/systrayIcon.png
Binary files differ
diff --git a/resources/images/impl/systray/systrayIconAway.png b/resources/images/impl/systray/systrayIconAway.png
index f503429..70466bf 100644
--- a/resources/images/impl/systray/systrayIconAway.png
+++ b/resources/images/impl/systray/systrayIconAway.png
Binary files differ
diff --git a/resources/images/impl/systray/systrayIconDND.png b/resources/images/impl/systray/systrayIconDND.png
index 9e45b4c..82afd62 100644
--- a/resources/images/impl/systray/systrayIconDND.png
+++ b/resources/images/impl/systray/systrayIconDND.png
Binary files differ
diff --git a/resources/images/impl/systray/systrayIconFFC.png b/resources/images/impl/systray/systrayIconFFC.png
index 46a8200..7f39e50 100644
--- a/resources/images/impl/systray/systrayIconFFC.png
+++ b/resources/images/impl/systray/systrayIconFFC.png
Binary files differ
diff --git a/resources/images/impl/systray/systrayIconOffline.png b/resources/images/impl/systray/systrayIconOffline.png
index 7db6479..39e1c8f 100644
--- a/resources/images/impl/systray/systrayIconOffline.png
+++ b/resources/images/impl/systray/systrayIconOffline.png
Binary files differ
diff --git a/resources/images/impl/systray/systrayIconWindows.png b/resources/images/impl/systray/systrayIconWindows.png
index 9708772..51939c7 100644
--- a/resources/images/impl/systray/systrayIconWindows.png
+++ b/resources/images/impl/systray/systrayIconWindows.png
Binary files differ
diff --git a/resources/images/impl/systray/systrayIconWindowsAway.png b/resources/images/impl/systray/systrayIconWindowsAway.png
index a5a110a..498fbcb 100644
--- a/resources/images/impl/systray/systrayIconWindowsAway.png
+++ b/resources/images/impl/systray/systrayIconWindowsAway.png
Binary files differ
diff --git a/resources/images/impl/systray/systrayIconWindowsDND.png b/resources/images/impl/systray/systrayIconWindowsDND.png
index d741398..5991993 100644
--- a/resources/images/impl/systray/systrayIconWindowsDND.png
+++ b/resources/images/impl/systray/systrayIconWindowsDND.png
Binary files differ
diff --git a/resources/images/impl/systray/systrayIconWindowsFFC.png b/resources/images/impl/systray/systrayIconWindowsFFC.png
index 97e9994..60cb1bd 100644
--- a/resources/images/impl/systray/systrayIconWindowsFFC.png
+++ b/resources/images/impl/systray/systrayIconWindowsFFC.png
Binary files differ
diff --git a/resources/images/impl/systray/systrayIconWindowsOffline.png b/resources/images/impl/systray/systrayIconWindowsOffline.png
index 8d3f8be..2b7907e 100644
--- a/resources/images/impl/systray/systrayIconWindowsOffline.png
+++ b/resources/images/impl/systray/systrayIconWindowsOffline.png
Binary files differ
diff --git a/resources/images/plugin/advancedconfig/configIcon.png b/resources/images/plugin/advancedconfig/configIcon.png
index 0689b0d..0b450db 100644
--- a/resources/images/plugin/advancedconfig/configIcon.png
+++ b/resources/images/plugin/advancedconfig/configIcon.png
Binary files differ
diff --git a/resources/images/plugin/chatconfig/chatIcon.png b/resources/images/plugin/chatconfig/chatIcon.png
index 7b8db43..a97cdfd 100644
--- a/resources/images/plugin/chatconfig/chatIcon.png
+++ b/resources/images/plugin/chatconfig/chatIcon.png
Binary files differ
diff --git a/resources/images/plugin/contactinfo/userInfo16x16.png b/resources/images/plugin/contactinfo/userInfo16x16.png
index 19210b3..7a2ef66 100644
--- a/resources/images/plugin/contactinfo/userInfo16x16.png
+++ b/resources/images/plugin/contactinfo/userInfo16x16.png
Binary files differ
diff --git a/resources/images/plugin/generalconfig/configureIcon.png b/resources/images/plugin/generalconfig/configureIcon.png
index f28d5cf..06014b3 100644
--- a/resources/images/plugin/generalconfig/configureIcon.png
+++ b/resources/images/plugin/generalconfig/configureIcon.png
Binary files differ
diff --git a/resources/images/plugin/notificationconfiguration/folder.png b/resources/images/plugin/notificationconfiguration/folder.png
index 35cf94f..a8b10ff 100644
--- a/resources/images/plugin/notificationconfiguration/folder.png
+++ b/resources/images/plugin/notificationconfiguration/folder.png
Binary files differ
diff --git a/resources/images/plugin/notificationconfiguration/playIcon.png b/resources/images/plugin/notificationconfiguration/playIcon.png
index ae438d1..4883c3f 100644
--- a/resources/images/plugin/notificationconfiguration/playIcon.png
+++ b/resources/images/plugin/notificationconfiguration/playIcon.png
Binary files differ
diff --git a/resources/images/plugin/notificationconfiguration/popupIcon.png b/resources/images/plugin/notificationconfiguration/popupIcon.png
index aa38c96..541da24 100644
--- a/resources/images/plugin/notificationconfiguration/popupIcon.png
+++ b/resources/images/plugin/notificationconfiguration/popupIcon.png
Binary files differ
diff --git a/resources/images/plugin/notificationconfiguration/progIcon.png b/resources/images/plugin/notificationconfiguration/progIcon.png
index b18a858..13ab51b 100644
--- a/resources/images/plugin/notificationconfiguration/progIcon.png
+++ b/resources/images/plugin/notificationconfiguration/progIcon.png
Binary files differ
diff --git a/resources/images/plugin/notificationconfiguration/soundIcon.png b/resources/images/plugin/notificationconfiguration/soundIcon.png
index 1630ec8..620173b 100644
--- a/resources/images/plugin/notificationconfiguration/soundIcon.png
+++ b/resources/images/plugin/notificationconfiguration/soundIcon.png
Binary files differ
diff --git a/resources/images/plugin/otr/encrypted22x22.png b/resources/images/plugin/otr/encrypted22x22.png
index aebe70d..8fdf6f2 100644
--- a/resources/images/plugin/otr/encrypted22x22.png
+++ b/resources/images/plugin/otr/encrypted22x22.png
Binary files differ
diff --git a/resources/images/plugin/otr/encrypted_unverified22x22.png b/resources/images/plugin/otr/encrypted_unverified22x22.png
index 83e0533..c4cd15d 100644
--- a/resources/images/plugin/otr/encrypted_unverified22x22.png
+++ b/resources/images/plugin/otr/encrypted_unverified22x22.png
Binary files differ
diff --git a/resources/images/plugin/otr/finished22x22.png b/resources/images/plugin/otr/finished22x22.png
index ce1ab26..e196297 100644
--- a/resources/images/plugin/otr/finished22x22.png
+++ b/resources/images/plugin/otr/finished22x22.png
Binary files differ
diff --git a/resources/images/plugin/otr/otr_menu_icon.png b/resources/images/plugin/otr/otr_menu_icon.png
index e29ac39..7909f88 100644
--- a/resources/images/plugin/otr/otr_menu_icon.png
+++ b/resources/images/plugin/otr/otr_menu_icon.png
Binary files differ
diff --git a/resources/images/plugin/otr/plaintext16x16.png b/resources/images/plugin/otr/plaintext16x16.png
index 8430368..9b190a1 100644
--- a/resources/images/plugin/otr/plaintext16x16.png
+++ b/resources/images/plugin/otr/plaintext16x16.png
Binary files differ
diff --git a/resources/images/plugin/otr/plaintext22x22.png b/resources/images/plugin/otr/plaintext22x22.png
index f105d84..6f38b39 100644
--- a/resources/images/plugin/otr/plaintext22x22.png
+++ b/resources/images/plugin/otr/plaintext22x22.png
Binary files differ
diff --git a/resources/images/plugin/securityconfig/security.png b/resources/images/plugin/securityconfig/security.png
index d10c256..11e8bbd 100644
--- a/resources/images/plugin/securityconfig/security.png
+++ b/resources/images/plugin/securityconfig/security.png
Binary files differ
diff --git a/resources/images/protocol/aim/aim16x16-away.png b/resources/images/protocol/aim/aim16x16-away.png
index 91629de..c049b75 100644
--- a/resources/images/protocol/aim/aim16x16-away.png
+++ b/resources/images/protocol/aim/aim16x16-away.png
Binary files differ
diff --git a/resources/images/protocol/aim/aim16x16-invisible.png b/resources/images/protocol/aim/aim16x16-invisible.png
index aa5a20d..b62512c 100644
--- a/resources/images/protocol/aim/aim16x16-invisible.png
+++ b/resources/images/protocol/aim/aim16x16-invisible.png
Binary files differ
diff --git a/resources/images/protocol/aim/aim16x16-offline.png b/resources/images/protocol/aim/aim16x16-offline.png
index 053c3b8..7057429 100644
--- a/resources/images/protocol/aim/aim16x16-offline.png
+++ b/resources/images/protocol/aim/aim16x16-offline.png
Binary files differ
diff --git a/resources/images/protocol/aim/aim16x16-online.png b/resources/images/protocol/aim/aim16x16-online.png
index 4530209..d85cbeb 100644
--- a/resources/images/protocol/aim/aim16x16-online.png
+++ b/resources/images/protocol/aim/aim16x16-online.png
Binary files differ
diff --git a/resources/images/protocol/aim/cr16-action-aim_connecting.png b/resources/images/protocol/aim/cr16-action-aim_connecting.png
new file mode 100644
index 0000000..fc52b3e
--- /dev/null
+++ b/resources/images/protocol/aim/cr16-action-aim_connecting.png
Binary files differ
diff --git a/resources/images/protocol/facebook/facebook-idle.png b/resources/images/protocol/facebook/facebook-idle.png
index 719698f..42654a4 100644
--- a/resources/images/protocol/facebook/facebook-idle.png
+++ b/resources/images/protocol/facebook/facebook-idle.png
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-away.png b/resources/images/protocol/facebook/status16x16-away.png
index 771d75f..fa449b8 100644
--- a/resources/images/protocol/facebook/status16x16-away.png
+++ b/resources/images/protocol/facebook/status16x16-away.png
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-connecting.png b/resources/images/protocol/facebook/status16x16-connecting.png
new file mode 100644
index 0000000..c205d7f
--- /dev/null
+++ b/resources/images/protocol/facebook/status16x16-connecting.png
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-dnd.png b/resources/images/protocol/facebook/status16x16-dnd.png
index 0bef0c3..22976e6 100644
--- a/resources/images/protocol/facebook/status16x16-dnd.png
+++ b/resources/images/protocol/facebook/status16x16-dnd.png
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-ffc.png b/resources/images/protocol/facebook/status16x16-ffc.png
index 7e081bd..196856b 100644
--- a/resources/images/protocol/facebook/status16x16-ffc.png
+++ b/resources/images/protocol/facebook/status16x16-ffc.png
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-invisible.png b/resources/images/protocol/facebook/status16x16-invisible.png
new file mode 100644
index 0000000..2571abc
--- /dev/null
+++ b/resources/images/protocol/facebook/status16x16-invisible.png
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-offline.png b/resources/images/protocol/facebook/status16x16-offline.png
index 50ed131..246972c 100644
--- a/resources/images/protocol/facebook/status16x16-offline.png
+++ b/resources/images/protocol/facebook/status16x16-offline.png
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-online.png b/resources/images/protocol/facebook/status16x16-online.png
index bc42cf9..4bc93a2 100644
--- a/resources/images/protocol/facebook/status16x16-online.png
+++ b/resources/images/protocol/facebook/status16x16-online.png
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-phone.png b/resources/images/protocol/facebook/status16x16-phone.png
index 0e96c20..9b3b4fc 100644
--- a/resources/images/protocol/facebook/status16x16-phone.png
+++ b/resources/images/protocol/facebook/status16x16-phone.png
Binary files differ
diff --git a/resources/images/protocol/facebook/status16x16-xa.png b/resources/images/protocol/facebook/status16x16-xa.png
index 719698f..ba5adb8 100644
--- a/resources/images/protocol/facebook/status16x16-xa.png
+++ b/resources/images/protocol/facebook/status16x16-xa.png
Binary files differ
diff --git a/resources/images/protocol/gibberish/gibberish-away.png b/resources/images/protocol/gibberish/gibberish-away.png
index cec4005..8304c5f 100644
--- a/resources/images/protocol/gibberish/gibberish-away.png
+++ b/resources/images/protocol/gibberish/gibberish-away.png
Binary files differ
diff --git a/resources/images/protocol/gibberish/gibberish-dnd.png b/resources/images/protocol/gibberish/gibberish-dnd.png
index c76cb05..1488375 100644
--- a/resources/images/protocol/gibberish/gibberish-dnd.png
+++ b/resources/images/protocol/gibberish/gibberish-dnd.png
Binary files differ
diff --git a/resources/images/protocol/gibberish/gibberish-ffc.png b/resources/images/protocol/gibberish/gibberish-ffc.png
index c1bdfe9..cdd3461 100644
--- a/resources/images/protocol/gibberish/gibberish-ffc.png
+++ b/resources/images/protocol/gibberish/gibberish-ffc.png
Binary files differ
diff --git a/resources/images/protocol/gibberish/gibberish-invisible.png b/resources/images/protocol/gibberish/gibberish-invisible.png
index 6dbac63..7999f5c 100644
--- a/resources/images/protocol/gibberish/gibberish-invisible.png
+++ b/resources/images/protocol/gibberish/gibberish-invisible.png
Binary files differ
diff --git a/resources/images/protocol/gibberish/gibberish-na.png b/resources/images/protocol/gibberish/gibberish-na.png
index b61d45c..ff95204 100644
--- a/resources/images/protocol/gibberish/gibberish-na.png
+++ b/resources/images/protocol/gibberish/gibberish-na.png
Binary files differ
diff --git a/resources/images/protocol/gibberish/gibberish-occupied.png b/resources/images/protocol/gibberish/gibberish-occupied.png
index 5e1b736..f3de24d 100644
--- a/resources/images/protocol/gibberish/gibberish-occupied.png
+++ b/resources/images/protocol/gibberish/gibberish-occupied.png
Binary files differ
diff --git a/resources/images/protocol/gibberish/gibberish-offline.png b/resources/images/protocol/gibberish/gibberish-offline.png
index fc892fa..085cad2 100644
--- a/resources/images/protocol/gibberish/gibberish-offline.png
+++ b/resources/images/protocol/gibberish/gibberish-offline.png
Binary files differ
diff --git a/resources/images/protocol/gibberish/gibberish-online.png b/resources/images/protocol/gibberish/gibberish-online.png
index fdbb633..98b845c 100644
--- a/resources/images/protocol/gibberish/gibberish-online.png
+++ b/resources/images/protocol/gibberish/gibberish-online.png
Binary files differ
diff --git a/resources/images/protocol/googletalk/status16x16-away.png b/resources/images/protocol/googletalk/status16x16-away.png
index ae8bb42..57f908c 100644
--- a/resources/images/protocol/googletalk/status16x16-away.png
+++ b/resources/images/protocol/googletalk/status16x16-away.png
Binary files differ
diff --git a/resources/images/protocol/googletalk/status16x16-connecting.png b/resources/images/protocol/googletalk/status16x16-connecting.png
new file mode 100644
index 0000000..88dc3f1
--- /dev/null
+++ b/resources/images/protocol/googletalk/status16x16-connecting.png
Binary files differ
diff --git a/resources/images/protocol/googletalk/status16x16-dnd.png b/resources/images/protocol/googletalk/status16x16-dnd.png
index e3b0e75..fb9f602 100644
--- a/resources/images/protocol/googletalk/status16x16-dnd.png
+++ b/resources/images/protocol/googletalk/status16x16-dnd.png
Binary files differ
diff --git a/resources/images/protocol/googletalk/status16x16-ffc.png b/resources/images/protocol/googletalk/status16x16-ffc.png
index 0c734e7..8ac108a 100644
--- a/resources/images/protocol/googletalk/status16x16-ffc.png
+++ b/resources/images/protocol/googletalk/status16x16-ffc.png
Binary files differ
diff --git a/resources/images/protocol/googletalk/status16x16-offline.png b/resources/images/protocol/googletalk/status16x16-offline.png
index 6071549..8f5325e 100644
--- a/resources/images/protocol/googletalk/status16x16-offline.png
+++ b/resources/images/protocol/googletalk/status16x16-offline.png
Binary files differ
diff --git a/resources/images/protocol/googletalk/status16x16-online.png b/resources/images/protocol/googletalk/status16x16-online.png
index e80b03b..c707f2a 100644
--- a/resources/images/protocol/googletalk/status16x16-online.png
+++ b/resources/images/protocol/googletalk/status16x16-online.png
Binary files differ
diff --git a/resources/images/protocol/googletalk/status16x16-phone.png b/resources/images/protocol/googletalk/status16x16-phone.png
index 5ede5dc..d8dfc8f 100644
--- a/resources/images/protocol/googletalk/status16x16-phone.png
+++ b/resources/images/protocol/googletalk/status16x16-phone.png
Binary files differ
diff --git a/resources/images/protocol/googletalk/status16x16-xa.png b/resources/images/protocol/googletalk/status16x16-xa.png
index a0ecc4f..d2e1f95 100644
--- a/resources/images/protocol/googletalk/status16x16-xa.png
+++ b/resources/images/protocol/googletalk/status16x16-xa.png
Binary files differ
diff --git a/resources/images/protocol/icq/cr16-action-icq_connecting-1.png b/resources/images/protocol/icq/cr16-action-icq_connecting-1.png
new file mode 100644
index 0000000..b89179c
--- /dev/null
+++ b/resources/images/protocol/icq/cr16-action-icq_connecting-1.png
Binary files differ
diff --git a/resources/images/protocol/icq/googletalk3_157.png b/resources/images/protocol/icq/googletalk3_157.png
new file mode 100644
index 0000000..de4e733
--- /dev/null
+++ b/resources/images/protocol/icq/googletalk3_157.png
Binary files differ
diff --git a/resources/images/protocol/icq/icq16x16-away.png b/resources/images/protocol/icq/icq16x16-away.png
index 79b5e0e..739b4c1 100644
--- a/resources/images/protocol/icq/icq16x16-away.png
+++ b/resources/images/protocol/icq/icq16x16-away.png
Binary files differ
diff --git a/resources/images/protocol/icq/icq16x16-dnd.png b/resources/images/protocol/icq/icq16x16-dnd.png
index 3db1c00..670dbeb 100644
--- a/resources/images/protocol/icq/icq16x16-dnd.png
+++ b/resources/images/protocol/icq/icq16x16-dnd.png
Binary files differ
diff --git a/resources/images/protocol/icq/icq16x16-ffc.png b/resources/images/protocol/icq/icq16x16-ffc.png
index 70ab6af..e8826aa 100644
--- a/resources/images/protocol/icq/icq16x16-ffc.png
+++ b/resources/images/protocol/icq/icq16x16-ffc.png
Binary files differ
diff --git a/resources/images/protocol/icq/icq16x16-invisible.png b/resources/images/protocol/icq/icq16x16-invisible.png
index c7e37ce..832e3ec 100644
--- a/resources/images/protocol/icq/icq16x16-invisible.png
+++ b/resources/images/protocol/icq/icq16x16-invisible.png
Binary files differ
diff --git a/resources/images/protocol/icq/icq16x16-na.png b/resources/images/protocol/icq/icq16x16-na.png
index 2e0b0d3..5247141 100644
--- a/resources/images/protocol/icq/icq16x16-na.png
+++ b/resources/images/protocol/icq/icq16x16-na.png
Binary files differ
diff --git a/resources/images/protocol/icq/icq16x16-occupied.png b/resources/images/protocol/icq/icq16x16-occupied.png
index 4b08b57..a6f3ea2 100644
--- a/resources/images/protocol/icq/icq16x16-occupied.png
+++ b/resources/images/protocol/icq/icq16x16-occupied.png
Binary files differ
diff --git a/resources/images/protocol/icq/icq16x16-offline.png b/resources/images/protocol/icq/icq16x16-offline.png
index a9d1103..1a6fdef 100644
--- a/resources/images/protocol/icq/icq16x16-offline.png
+++ b/resources/images/protocol/icq/icq16x16-offline.png
Binary files differ
diff --git a/resources/images/protocol/icq/icq16x16-online.png b/resources/images/protocol/icq/icq16x16-online.png
index 900ee44..ea66631 100644
--- a/resources/images/protocol/icq/icq16x16-online.png
+++ b/resources/images/protocol/icq/icq16x16-online.png
Binary files differ
diff --git a/resources/images/protocol/ippi/sip16x16-away.png b/resources/images/protocol/ippi/sip16x16-away.png
index 24ef080..9189f18 100644
--- a/resources/images/protocol/ippi/sip16x16-away.png
+++ b/resources/images/protocol/ippi/sip16x16-away.png
Binary files differ
diff --git a/resources/images/protocol/ippi/sip16x16-busy.png b/resources/images/protocol/ippi/sip16x16-busy.png
index 27a0dde..fcc6181 100644
--- a/resources/images/protocol/ippi/sip16x16-busy.png
+++ b/resources/images/protocol/ippi/sip16x16-busy.png
Binary files differ
diff --git a/resources/images/protocol/ippi/sip16x16-offline.png b/resources/images/protocol/ippi/sip16x16-offline.png
index 9502b87..fc888ad 100644
--- a/resources/images/protocol/ippi/sip16x16-offline.png
+++ b/resources/images/protocol/ippi/sip16x16-offline.png
Binary files differ
diff --git a/resources/images/protocol/ippi/sip16x16-online.png b/resources/images/protocol/ippi/sip16x16-online.png
index e30b77c..e203a69 100644
--- a/resources/images/protocol/ippi/sip16x16-online.png
+++ b/resources/images/protocol/ippi/sip16x16-online.png
Binary files differ
diff --git a/resources/images/protocol/ippi/sip16x16-phone.png b/resources/images/protocol/ippi/sip16x16-phone.png
index 321ce8a..1db411f 100644
--- a/resources/images/protocol/ippi/sip16x16-phone.png
+++ b/resources/images/protocol/ippi/sip16x16-phone.png
Binary files differ
diff --git a/resources/images/protocol/iptel/sip-connecting.png b/resources/images/protocol/iptel/sip-connecting.png
new file mode 100644
index 0000000..23f16ff
--- /dev/null
+++ b/resources/images/protocol/iptel/sip-connecting.png
Binary files differ
diff --git a/resources/images/protocol/iptel/sip16x16-away.png b/resources/images/protocol/iptel/sip16x16-away.png
index 826ccf5..9c7e93c 100644
--- a/resources/images/protocol/iptel/sip16x16-away.png
+++ b/resources/images/protocol/iptel/sip16x16-away.png
Binary files differ
diff --git a/resources/images/protocol/iptel/sip16x16-busy.png b/resources/images/protocol/iptel/sip16x16-busy.png
index 4847c44..3b8431f 100644
--- a/resources/images/protocol/iptel/sip16x16-busy.png
+++ b/resources/images/protocol/iptel/sip16x16-busy.png
Binary files differ
diff --git a/resources/images/protocol/iptel/sip16x16-offline.png b/resources/images/protocol/iptel/sip16x16-offline.png
index 4295d20..499d85f 100644
--- a/resources/images/protocol/iptel/sip16x16-offline.png
+++ b/resources/images/protocol/iptel/sip16x16-offline.png
Binary files differ
diff --git a/resources/images/protocol/iptel/sip16x16-online.png b/resources/images/protocol/iptel/sip16x16-online.png
index b361b7f..68b460b 100644
--- a/resources/images/protocol/iptel/sip16x16-online.png
+++ b/resources/images/protocol/iptel/sip16x16-online.png
Binary files differ
diff --git a/resources/images/protocol/iptel/sip16x16-phone.png b/resources/images/protocol/iptel/sip16x16-phone.png
index 01db50a..10de01e 100644
--- a/resources/images/protocol/iptel/sip16x16-phone.png
+++ b/resources/images/protocol/iptel/sip16x16-phone.png
Binary files differ
diff --git a/resources/images/protocol/irc/cr16-action-irc_away.png b/resources/images/protocol/irc/cr16-action-irc_away.png
index d7572e1..9fb5e19 100644
--- a/resources/images/protocol/irc/cr16-action-irc_away.png
+++ b/resources/images/protocol/irc/cr16-action-irc_away.png
Binary files differ
diff --git a/resources/images/protocol/irc/cr16-action-irc_connecting-1.png b/resources/images/protocol/irc/cr16-action-irc_connecting-1.png
new file mode 100644
index 0000000..0df6487
--- /dev/null
+++ b/resources/images/protocol/irc/cr16-action-irc_connecting-1.png
Binary files differ
diff --git a/resources/images/protocol/irc/cr16-action-irc_offline.png b/resources/images/protocol/irc/cr16-action-irc_offline.png
index fe5894a..f4c69dd 100644
--- a/resources/images/protocol/irc/cr16-action-irc_offline.png
+++ b/resources/images/protocol/irc/cr16-action-irc_offline.png
Binary files differ
diff --git a/resources/images/protocol/irc/cr16-action-irc_online.png b/resources/images/protocol/irc/cr16-action-irc_online.png
index c5678d1..147ad6f 100644
--- a/resources/images/protocol/irc/cr16-action-irc_online.png
+++ b/resources/images/protocol/irc/cr16-action-irc_online.png
Binary files differ
diff --git a/resources/images/protocol/irc/cr16-action-irc_op.png b/resources/images/protocol/irc/cr16-action-irc_op.png
index 6b14cf1..dbdaf1a 100644
--- a/resources/images/protocol/irc/cr16-action-irc_op.png
+++ b/resources/images/protocol/irc/cr16-action-irc_op.png
Binary files differ
diff --git a/resources/images/protocol/irc/cr16-action-irc_server.png b/resources/images/protocol/irc/cr16-action-irc_server.png
index b7a3cc2..7a19dea 100644
--- a/resources/images/protocol/irc/cr16-action-irc_server.png
+++ b/resources/images/protocol/irc/cr16-action-irc_server.png
Binary files differ
diff --git a/resources/images/protocol/irc/cr16-action-irc_voice.png b/resources/images/protocol/irc/cr16-action-irc_voice.png
index 6a9b5aa..a3a171d 100644
--- a/resources/images/protocol/irc/cr16-action-irc_voice.png
+++ b/resources/images/protocol/irc/cr16-action-irc_voice.png
Binary files differ
diff --git a/resources/images/protocol/irc/googletalk3_131.png b/resources/images/protocol/irc/googletalk3_131.png
new file mode 100644
index 0000000..6ed26c4
--- /dev/null
+++ b/resources/images/protocol/irc/googletalk3_131.png
Binary files differ
diff --git a/resources/images/protocol/jabber/status16x16-away.png b/resources/images/protocol/jabber/status16x16-away.png
index 23ba92f..27459b9 100644
--- a/resources/images/protocol/jabber/status16x16-away.png
+++ b/resources/images/protocol/jabber/status16x16-away.png
Binary files differ
diff --git a/resources/images/protocol/jabber/status16x16-connecting.png b/resources/images/protocol/jabber/status16x16-connecting.png
new file mode 100644
index 0000000..4fc0929
--- /dev/null
+++ b/resources/images/protocol/jabber/status16x16-connecting.png
Binary files differ
diff --git a/resources/images/protocol/jabber/status16x16-dnd.png b/resources/images/protocol/jabber/status16x16-dnd.png
index 2655057..b9c18d1 100644
--- a/resources/images/protocol/jabber/status16x16-dnd.png
+++ b/resources/images/protocol/jabber/status16x16-dnd.png
Binary files differ
diff --git a/resources/images/protocol/jabber/status16x16-ffc.png b/resources/images/protocol/jabber/status16x16-ffc.png
index 3e553ba..cbe204e 100644
--- a/resources/images/protocol/jabber/status16x16-ffc.png
+++ b/resources/images/protocol/jabber/status16x16-ffc.png
Binary files differ
diff --git a/resources/images/protocol/jabber/status16x16-offline.png b/resources/images/protocol/jabber/status16x16-offline.png
index 7989eb7..9b54661 100644
--- a/resources/images/protocol/jabber/status16x16-offline.png
+++ b/resources/images/protocol/jabber/status16x16-offline.png
Binary files differ
diff --git a/resources/images/protocol/jabber/status16x16-online.png b/resources/images/protocol/jabber/status16x16-online.png
index 918cd6e..81b2cf6 100644
--- a/resources/images/protocol/jabber/status16x16-online.png
+++ b/resources/images/protocol/jabber/status16x16-online.png
Binary files differ
diff --git a/resources/images/protocol/jabber/status16x16-phone.png b/resources/images/protocol/jabber/status16x16-phone.png
index b9e3d7c..94599ff 100644
--- a/resources/images/protocol/jabber/status16x16-phone.png
+++ b/resources/images/protocol/jabber/status16x16-phone.png
Binary files differ
diff --git a/resources/images/protocol/jabber/status16x16-xa.png b/resources/images/protocol/jabber/status16x16-xa.png
index 7602bb5..8704870 100644
--- a/resources/images/protocol/jabber/status16x16-xa.png
+++ b/resources/images/protocol/jabber/status16x16-xa.png
Binary files differ
diff --git a/resources/images/protocol/msn/msn16x16-away.png b/resources/images/protocol/msn/msn16x16-away.png
index 67e3468..77887af 100644
--- a/resources/images/protocol/msn/msn16x16-away.png
+++ b/resources/images/protocol/msn/msn16x16-away.png
Binary files differ
diff --git a/resources/images/protocol/msn/msn16x16-brb.png b/resources/images/protocol/msn/msn16x16-brb.png
index 3853ab6..f59d99b 100644
--- a/resources/images/protocol/msn/msn16x16-brb.png
+++ b/resources/images/protocol/msn/msn16x16-brb.png
Binary files differ
diff --git a/resources/images/protocol/msn/msn16x16-busy.png b/resources/images/protocol/msn/msn16x16-busy.png
index c715364..e77cec3 100644
--- a/resources/images/protocol/msn/msn16x16-busy.png
+++ b/resources/images/protocol/msn/msn16x16-busy.png
Binary files differ
diff --git a/resources/images/protocol/msn/msn16x16-connecting.png b/resources/images/protocol/msn/msn16x16-connecting.png
new file mode 100644
index 0000000..58e5502
--- /dev/null
+++ b/resources/images/protocol/msn/msn16x16-connecting.png
Binary files differ
diff --git a/resources/images/protocol/msn/msn16x16-invisible.png b/resources/images/protocol/msn/msn16x16-invisible.png
index 5997618..7c803b6 100644
--- a/resources/images/protocol/msn/msn16x16-invisible.png
+++ b/resources/images/protocol/msn/msn16x16-invisible.png
Binary files differ
diff --git a/resources/images/protocol/msn/msn16x16-lunch.png b/resources/images/protocol/msn/msn16x16-lunch.png
index e9b54ca..c4381b3 100644
--- a/resources/images/protocol/msn/msn16x16-lunch.png
+++ b/resources/images/protocol/msn/msn16x16-lunch.png
Binary files differ
diff --git a/resources/images/protocol/msn/msn16x16-na.png b/resources/images/protocol/msn/msn16x16-na.png
index ad76824..2d9f653 100644
--- a/resources/images/protocol/msn/msn16x16-na.png
+++ b/resources/images/protocol/msn/msn16x16-na.png
Binary files differ
diff --git a/resources/images/protocol/msn/msn16x16-offline.png b/resources/images/protocol/msn/msn16x16-offline.png
index 1662d65..b16e848 100644
--- a/resources/images/protocol/msn/msn16x16-offline.png
+++ b/resources/images/protocol/msn/msn16x16-offline.png
Binary files differ
diff --git a/resources/images/protocol/msn/msn16x16-online.png b/resources/images/protocol/msn/msn16x16-online.png
index a6dcfe9..61c08c8 100644
--- a/resources/images/protocol/msn/msn16x16-online.png
+++ b/resources/images/protocol/msn/msn16x16-online.png
Binary files differ
diff --git a/resources/images/protocol/msn/msn16x16-phone.png b/resources/images/protocol/msn/msn16x16-phone.png
index d04b378..92b797a 100644
--- a/resources/images/protocol/msn/msn16x16-phone.png
+++ b/resources/images/protocol/msn/msn16x16-phone.png
Binary files differ
diff --git a/resources/images/protocol/sip/sip-connecting.png b/resources/images/protocol/sip/sip-connecting.png
new file mode 100644
index 0000000..3709a52
--- /dev/null
+++ b/resources/images/protocol/sip/sip-connecting.png
Binary files differ
diff --git a/resources/images/protocol/sip/sip16x16-away.png b/resources/images/protocol/sip/sip16x16-away.png
index 94539c3..7872056 100644
--- a/resources/images/protocol/sip/sip16x16-away.png
+++ b/resources/images/protocol/sip/sip16x16-away.png
Binary files differ
diff --git a/resources/images/protocol/sip/sip16x16-busy.png b/resources/images/protocol/sip/sip16x16-busy.png
index 295dcfc..299e2fc 100644
--- a/resources/images/protocol/sip/sip16x16-busy.png
+++ b/resources/images/protocol/sip/sip16x16-busy.png
Binary files differ
diff --git a/resources/images/protocol/sip/sip16x16-offline.png b/resources/images/protocol/sip/sip16x16-offline.png
index ab47e5a..ecb6d4c 100644
--- a/resources/images/protocol/sip/sip16x16-offline.png
+++ b/resources/images/protocol/sip/sip16x16-offline.png
Binary files differ
diff --git a/resources/images/protocol/sip/sip16x16-online.png b/resources/images/protocol/sip/sip16x16-online.png
index cc8e0d4..b6801b6 100644
--- a/resources/images/protocol/sip/sip16x16-online.png
+++ b/resources/images/protocol/sip/sip16x16-online.png
Binary files differ
diff --git a/resources/images/protocol/sip/sip16x16-phone.png b/resources/images/protocol/sip/sip16x16-phone.png
index b056a34..279d396 100644
--- a/resources/images/protocol/sip/sip16x16-phone.png
+++ b/resources/images/protocol/sip/sip16x16-phone.png
Binary files differ
diff --git a/resources/images/protocol/sip2sip/sip16x16-away.png b/resources/images/protocol/sip2sip/sip16x16-away.png
index 2212efd..cc2d146 100644
--- a/resources/images/protocol/sip2sip/sip16x16-away.png
+++ b/resources/images/protocol/sip2sip/sip16x16-away.png
Binary files differ
diff --git a/resources/images/protocol/sip2sip/sip16x16-busy.png b/resources/images/protocol/sip2sip/sip16x16-busy.png
index 257c307..b3e14e2 100644
--- a/resources/images/protocol/sip2sip/sip16x16-busy.png
+++ b/resources/images/protocol/sip2sip/sip16x16-busy.png
Binary files differ
diff --git a/resources/images/protocol/sip2sip/sip16x16-offline.png b/resources/images/protocol/sip2sip/sip16x16-offline.png
index 8506462..ca74f64 100644
--- a/resources/images/protocol/sip2sip/sip16x16-offline.png
+++ b/resources/images/protocol/sip2sip/sip16x16-offline.png
Binary files differ
diff --git a/resources/images/protocol/sip2sip/sip16x16-online.png b/resources/images/protocol/sip2sip/sip16x16-online.png
index 389e583..cd05e31 100644
--- a/resources/images/protocol/sip2sip/sip16x16-online.png
+++ b/resources/images/protocol/sip2sip/sip16x16-online.png
Binary files differ
diff --git a/resources/images/protocol/sip2sip/sip16x16-phone.png b/resources/images/protocol/sip2sip/sip16x16-phone.png
index 914d2e7..0babceb 100644
--- a/resources/images/protocol/sip2sip/sip16x16-phone.png
+++ b/resources/images/protocol/sip2sip/sip16x16-phone.png
Binary files differ
diff --git a/resources/images/protocol/ssh/ssh-connected.png b/resources/images/protocol/ssh/ssh-connected.png
index 9135523..ac168e0 100644
--- a/resources/images/protocol/ssh/ssh-connected.png
+++ b/resources/images/protocol/ssh/ssh-connected.png
Binary files differ
diff --git a/resources/images/protocol/ssh/ssh-connecting.png b/resources/images/protocol/ssh/ssh-connecting.png
index 47f61ae..5ae7f03 100644
--- a/resources/images/protocol/ssh/ssh-connecting.png
+++ b/resources/images/protocol/ssh/ssh-connecting.png
Binary files differ
diff --git a/resources/images/protocol/ssh/ssh-filetransfer.png b/resources/images/protocol/ssh/ssh-filetransfer.png
index d92d6aa..50eca81 100644
--- a/resources/images/protocol/ssh/ssh-filetransfer.png
+++ b/resources/images/protocol/ssh/ssh-filetransfer.png
Binary files differ
diff --git a/resources/images/protocol/ssh/ssh-na.png b/resources/images/protocol/ssh/ssh-na.png
index d0d6265..90e5028 100644
--- a/resources/images/protocol/ssh/ssh-na.png
+++ b/resources/images/protocol/ssh/ssh-na.png
Binary files differ
diff --git a/resources/images/protocol/ssh/ssh-offline.png b/resources/images/protocol/ssh/ssh-offline.png
index 51c83b2..c8c429a 100644
--- a/resources/images/protocol/ssh/ssh-offline.png
+++ b/resources/images/protocol/ssh/ssh-offline.png
Binary files differ
diff --git a/resources/images/protocol/ssh/ssh-online.png b/resources/images/protocol/ssh/ssh-online.png
index 14683db..e67f418 100644
--- a/resources/images/protocol/ssh/ssh-online.png
+++ b/resources/images/protocol/ssh/ssh-online.png
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-away.png b/resources/images/protocol/yahoo/yahoo16x16-away.png
index 43df89d..84233cb 100644
--- a/resources/images/protocol/yahoo/yahoo16x16-away.png
+++ b/resources/images/protocol/yahoo/yahoo16x16-away.png
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-busy.png b/resources/images/protocol/yahoo/yahoo16x16-busy.png
index 760da06..22d2a02 100644
--- a/resources/images/protocol/yahoo/yahoo16x16-busy.png
+++ b/resources/images/protocol/yahoo/yahoo16x16-busy.png
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-connecting.png b/resources/images/protocol/yahoo/yahoo16x16-connecting.png
new file mode 100644
index 0000000..ff2e1d0
--- /dev/null
+++ b/resources/images/protocol/yahoo/yahoo16x16-connecting.png
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-idle.png b/resources/images/protocol/yahoo/yahoo16x16-idle.png
index 155544b..9965aec 100644
--- a/resources/images/protocol/yahoo/yahoo16x16-idle.png
+++ b/resources/images/protocol/yahoo/yahoo16x16-idle.png
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-invisible.png b/resources/images/protocol/yahoo/yahoo16x16-invisible.png
index 076f22e..6141e89 100644
--- a/resources/images/protocol/yahoo/yahoo16x16-invisible.png
+++ b/resources/images/protocol/yahoo/yahoo16x16-invisible.png
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-lunch.png b/resources/images/protocol/yahoo/yahoo16x16-lunch.png
index 534cf41..3ebf985 100644
--- a/resources/images/protocol/yahoo/yahoo16x16-lunch.png
+++ b/resources/images/protocol/yahoo/yahoo16x16-lunch.png
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-na.png b/resources/images/protocol/yahoo/yahoo16x16-na.png
index 0fea3c6..9fe7984 100644
--- a/resources/images/protocol/yahoo/yahoo16x16-na.png
+++ b/resources/images/protocol/yahoo/yahoo16x16-na.png
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-offline.png b/resources/images/protocol/yahoo/yahoo16x16-offline.png
index e3e8733..a6144f8 100644
--- a/resources/images/protocol/yahoo/yahoo16x16-offline.png
+++ b/resources/images/protocol/yahoo/yahoo16x16-offline.png
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-online.png b/resources/images/protocol/yahoo/yahoo16x16-online.png
index d144cab..a04a0fb 100644
--- a/resources/images/protocol/yahoo/yahoo16x16-online.png
+++ b/resources/images/protocol/yahoo/yahoo16x16-online.png
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-phone.png b/resources/images/protocol/yahoo/yahoo16x16-phone.png
index 01fa92b..0ef5cf8 100644
--- a/resources/images/protocol/yahoo/yahoo16x16-phone.png
+++ b/resources/images/protocol/yahoo/yahoo16x16-phone.png
Binary files differ
diff --git a/resources/images/protocol/yahoo/yahoo16x16-vacation.png b/resources/images/protocol/yahoo/yahoo16x16-vacation.png
index de0f7e7..5ebb3dc 100644
--- a/resources/images/protocol/yahoo/yahoo16x16-vacation.png
+++ b/resources/images/protocol/yahoo/yahoo16x16-vacation.png
Binary files differ
diff --git a/resources/images/protocol/zeroconf/zeroconf-away.png b/resources/images/protocol/zeroconf/zeroconf-away.png
index 2ecf4bc..8265d5a 100644
--- a/resources/images/protocol/zeroconf/zeroconf-away.png
+++ b/resources/images/protocol/zeroconf/zeroconf-away.png
Binary files differ
diff --git a/resources/images/protocol/zeroconf/zeroconf-dnd.png b/resources/images/protocol/zeroconf/zeroconf-dnd.png
index 23bd067..fa1b70b 100644
--- a/resources/images/protocol/zeroconf/zeroconf-dnd.png
+++ b/resources/images/protocol/zeroconf/zeroconf-dnd.png
Binary files differ
diff --git a/resources/images/protocol/zeroconf/zeroconf-invisible.png b/resources/images/protocol/zeroconf/zeroconf-invisible.png
index 35dd6b4..e3bd0cf 100644
--- a/resources/images/protocol/zeroconf/zeroconf-invisible.png
+++ b/resources/images/protocol/zeroconf/zeroconf-invisible.png
Binary files differ
diff --git a/resources/images/protocol/zeroconf/zeroconf-offline.png b/resources/images/protocol/zeroconf/zeroconf-offline.png
index 35609ff..de37240 100644
--- a/resources/images/protocol/zeroconf/zeroconf-offline.png
+++ b/resources/images/protocol/zeroconf/zeroconf-offline.png
Binary files differ
diff --git a/resources/images/protocol/zeroconf/zeroconf-online.png b/resources/images/protocol/zeroconf/zeroconf-online.png
index 3bde6f6..be66b1b 100644
--- a/resources/images/protocol/zeroconf/zeroconf-online.png
+++ b/resources/images/protocol/zeroconf/zeroconf-online.png
Binary files differ
diff --git a/resources/styles/defaultStyle.css b/resources/styles/defaultStyle.css
index a737e43..356cecd 100644
--- a/resources/styles/defaultStyle.css
+++ b/resources/styles/defaultStyle.css
@@ -1,6 +1,6 @@
h1
{
- background-color: #c6d0e1;
+ background-color: #6a6868;
margin: 0px;
text-align: center;
font-weight: bold;
@@ -10,14 +10,18 @@ h1
h2
{
margin: 0px;
- font-size: 100%;
- color: #ef7b1e;
+ padding-top: 4px;
+ padding-left: 10px;
+ font-size: 10px;
+ color: #488fe7;
}
h3
{
margin: 0px;
- font-size: 100%;
+ padding-top: 4px;
+ padding-left: 10px;
+ font-size: 10px;
color: #2e538b;
}
@@ -47,8 +51,8 @@ h6
p
{
margin: 0px;
+ width: 100%;
font-size: 100%;
- font-weight: bold;
color: #62BD80;
}
diff --git a/resources/styles/defaultStyle.txt b/resources/styles/defaultStyle.txt
new file mode 100644
index 0000000..60badf5
--- /dev/null
+++ b/resources/styles/defaultStyle.txt
@@ -0,0 +1,65 @@
+h1
+{
+ background-color: #6a6868;
+ margin: 0px;
+ text-align: center;
+ font-weight: bold;
+ font-size: 100%;
+}
+
+h2
+{
+ margin: 0px;
+ font-size: 100%;
+ color: #488fe7;
+}
+
+h3
+{
+ margin: 0px;
+ font-size: 100%;
+ color: #2e538b;
+}
+
+h4
+{
+ margin: 0px;
+ font-size: 100%;
+ font-weight: bold;
+ color: #FFC875;
+}
+
+h5
+{
+ margin: 0px;
+ font-size: 100%;
+ font-weight: bold;
+ color: #CC0000;
+}
+
+h6
+{
+ margin: 0px;
+ font-size: 100%;
+ font-weight: bold;
+ color: #990000;
+}
+p
+{
+ margin: 0px;
+ width: 100%;
+ font-size: 100%;
+ font-weight: bold;
+ color: #62BD80;
+}
+
+div
+{
+ font-size: 100%;
+ color: #000000;
+}
+
+h7
+{
+ background-color: #FFF4AB;
+}
diff --git a/resources/styles/stylebackup.txt b/resources/styles/stylebackup.txt
new file mode 100644
index 0000000..acedf98
--- /dev/null
+++ b/resources/styles/stylebackup.txt
@@ -0,0 +1,1949 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.gui.main.chat;
+
+import java.awt.*;
+import java.awt.datatransfer.*;
+import java.awt.event.*;
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import java.util.Map.Entry;
+import java.util.Map;
+import java.util.regex.*;
+
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.text.*;
+import javax.swing.text.html.*;
+import javax.swing.text.html.HTML.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.customcontrols.*;
+import net.java.sip.communicator.impl.gui.main.chat.history.*;
+import net.java.sip.communicator.impl.gui.main.chat.menus.*;
+import net.java.sip.communicator.impl.gui.utils.*;
+import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.replacement.*;
+import net.java.sip.communicator.service.replacement.smilies.*;
+import net.java.sip.communicator.util.*;
+import net.java.sip.communicator.util.skin.*;
+import net.java.sip.communicator.util.swing.*;
+import net.java.sip.communicator.util.swing.SwingWorker;
+
+/**
+ * The <tt>ChatConversationPanel</tt> is the panel, where all sent and received
+ * messages appear. All data is stored in an HTML document. An external CSS file
+ * is applied to the document to provide the look&feel. All smileys and link
+ * strings are processed and finally replaced by corresponding images and HTML
+ * links.
+ *
+ * @author Yana Stamcheva
+ * @author Lubomir Marinov
+ * @author Adam Netocny
+ */
+public class ChatConversationPanel
+ extends SCScrollPane
+ implements HyperlinkListener,
+ MouseListener,
+ ClipboardOwner,
+ Skinnable
+{
+ /**
+ * The <tt>Logger</tt> used by the <tt>ChatConversationPanel</tt> class and
+ * its instances for logging output.
+ */
+ private static final Logger logger
+ = Logger.getLogger(ChatConversationPanel.class);
+
+ /**
+ * The closing tag of the <code>PLAINTEXT</code> HTML element.
+ */
+ private static final String END_PLAINTEXT_TAG = "</PLAINTEXT>";
+
+ /**
+ * The opening tag of the <code>PLAINTEXT</code> HTML element.
+ */
+ private static final String START_PLAINTEXT_TAG = "<PLAINTEXT>";
+
+ /**
+ * The regular expression (in the form of compiled <tt>Pattern</tt>) which
+ * matches URLs for the purposed of turning them into links.
+ */
+ private static final Pattern URL_PATTERN
+ = Pattern.compile(
+ "("
+ + "(\\bwww\\.[^\\s<>\"]+\\.[^\\s<>\"]+/*[?#]*(\\w+[&=;?]\\w+)*\\b)" // wwwURL
+ + "|"
+ + "(\\bjitsi\\:[^\\s<>\"]+\\.[^\\s<>\"]*\\b)" // internalURL
+ + "|"
+ + "(\\b\\w+://[^\\s<>\"]+/*[?#]*(\\w+[&=;?]\\w+)*\\b)" // protocolURL
+ + ")");
+
+ /**
+ * List for observing text messages.
+ */
+ private Set<ChatLinkClickedListener> chatLinkClickedListeners =
+ new HashSet<ChatLinkClickedListener>();
+
+ /**
+ * The component rendering chat conversation panel text.
+ */
+ private final JTextPane chatTextPane = new MyTextPane();
+
+ /**
+ * The editor kit used by the text component.
+ */
+ private final HTMLEditorKit editorKit;
+
+ /**
+ * The document used by the text component.
+ */
+ private HTMLDocument document;
+
+ /**
+ * The parent container.
+ */
+ private final ChatConversationContainer chatContainer;
+
+ /**
+ * The menu shown on right button mouse click.
+ */
+ private final ChatRightButtonMenu rightButtonMenu;
+
+ /**
+ * The currently shown href.
+ */
+ private String currentHref;
+
+ /**
+ * The copy link item, contained in the right mouse click menu.
+ */
+ private final JMenuItem copyLinkItem;
+
+ /**
+ * The open link item, contained in the right mouse click menu.
+ */
+ private final JMenuItem openLinkItem;
+
+ /**
+ * The right mouse click menu separator.
+ */
+ private final JSeparator copyLinkSeparator = new JSeparator();
+
+ /**
+ * The timestamp of the last incoming message.
+ */
+ private long lastIncomingMsgTimestamp;
+
+ /**
+ * Indicates if this component is rendering a history conversation.
+ */
+ private final boolean isHistory;
+
+ /**
+ * The html text content type.
+ */
+ public static final String HTML_CONTENT_TYPE = "text/html";
+
+ /**
+ * The plain text content type.
+ */
+ public static final String TEXT_CONTENT_TYPE = "text/plain";
+
+ /**
+ * The indicator which determines whether an automatic scroll to the bottom
+ * of {@link #chatTextPane} is to be performed.
+ */
+ private boolean scrollToBottomIsPending = false;
+
+ private final static String INCOMING_MESSAGE_IMAGE_PATH
+ = GuiActivator.getResources().getImageURL(
+ "service.gui.lookandfeel.INCOMING_MESSAGE_BACKGROUND").toString();
+
+ /**
+ * The implementation of the routine which scrolls {@link #chatTextPane} to its
+ * bottom.
+ */
+ private final Runnable scrollToBottomRunnable = new Runnable()
+ {
+ /*
+ * Implements Runnable#run().
+ */
+ public void run()
+ {
+ JScrollBar verticalScrollBar = getVerticalScrollBar();
+
+ if (verticalScrollBar != null)
+ {
+ // We need to call both methods in order to be sure to scroll
+ // to the bottom of the text even when the user has selected
+ // something (changed the caret) or when a new tab has been
+ // added or the window has been resized.
+ verticalScrollBar.setValue(verticalScrollBar.getMaximum());
+ chatTextPane.setCaretPosition(document.getLength());
+ }
+ }
+ };
+
+ /**
+ * Creates an instance of <tt>ChatConversationPanel</tt>.
+ *
+ * @param chatContainer The parent <tt>ChatConversationContainer</tt>.
+ */
+ public ChatConversationPanel(ChatConversationContainer chatContainer)
+ {
+ editorKit = new SIPCommHTMLEditorKit(this);
+
+ this.chatContainer = chatContainer;
+
+ isHistory = (chatContainer instanceof HistoryWindow);
+
+ this.rightButtonMenu = new ChatRightButtonMenu(this);
+
+ this.document = (HTMLDocument) editorKit.createDefaultDocument();
+
+ this.chatTextPane.setEditorKitForContentType("text/html", editorKit);
+ this.chatTextPane.setEditorKit(editorKit);
+ this.chatTextPane.setEditable(false);
+ this.chatTextPane.setDocument(document);
+ this.chatTextPane.setDragEnabled(true);
+
+ chatTextPane.putClientProperty(
+ JEditorPane.HONOR_DISPLAY_PROPERTIES, Boolean.TRUE);
+ Constants.loadSimpleStyle(
+ document.getStyleSheet(), chatTextPane.getFont());
+
+ this.chatTextPane.addHyperlinkListener(this);
+ this.chatTextPane.addMouseListener(this);
+ this.chatTextPane.setCursor(
+ Cursor.getPredefinedCursor(Cursor.TEXT_CURSOR));
+
+ this.setWheelScrollingEnabled(true);
+
+ this.setViewportView(chatTextPane);
+
+ this.setBorder(null);
+
+ this.setHorizontalScrollBarPolicy(
+ JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
+
+ ToolTipManager.sharedInstance().registerComponent(chatTextPane);
+
+ String copyLinkString
+ = GuiActivator.getResources().getI18NString("service.gui.COPY_LINK");
+
+ copyLinkItem
+ = new JMenuItem(copyLinkString,
+ new ImageIcon(ImageLoader.getImage(ImageLoader.COPY_ICON)));
+
+ copyLinkItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ StringSelection stringSelection = new StringSelection(
+ currentHref);
+ Clipboard clipboard = Toolkit.getDefaultToolkit()
+ .getSystemClipboard();
+ clipboard.setContents(stringSelection,
+ ChatConversationPanel.this);
+ }
+ });
+
+ String openLinkString
+ = GuiActivator.getResources().getI18NString(
+ "service.gui.OPEN_IN_BROWSER");
+
+ openLinkItem =
+ new JMenuItem(
+ openLinkString,
+ new ImageIcon(ImageLoader.getImage(ImageLoader.BROWSER_ICON)));
+
+ openLinkItem.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ GuiActivator.getBrowserLauncher().openURL(currentHref);
+
+ // after opening the link remove the currentHref to avoid
+ // clicking on the window to gain focus to open the link again
+ ChatConversationPanel.this.currentHref = "";
+ }
+ });
+
+ openLinkItem.setMnemonic(
+ GuiActivator.getResources().getI18nMnemonic(
+ "service.gui.OPEN_IN_BROWSER"));
+
+ copyLinkItem.setMnemonic(
+ GuiActivator.getResources().getI18nMnemonic(
+ "service.gui.COPY_LINK"));
+
+ /*
+ * When we append a new message (regardless of whether it is a string or
+ * an UI component), we want to make it visible in the viewport of this
+ * JScrollPane so that the user can see it.
+ */
+ ComponentListener componentListener = new ComponentAdapter()
+ {
+ @Override
+ public void componentResized(ComponentEvent e)
+ {
+ synchronized (scrollToBottomRunnable)
+ {
+ if (!scrollToBottomIsPending)
+ return;
+ scrollToBottomIsPending = false;
+
+ /*
+ * Yana Stamcheva, pointed out that Java 5 (on Linux only?)
+ * needs invokeLater for JScrollBar.
+ */
+ SwingUtilities.invokeLater(scrollToBottomRunnable);
+ }
+ }
+ };
+
+ chatTextPane.addComponentListener(componentListener);
+ getViewport().addComponentListener(componentListener);
+ }
+
+ /**
+ * Overrides Component#setBounds(int, int, int, int) in order to determine
+ * whether an automatic scroll of #chatTextPane to its bottom will be
+ * necessary at a later time in order to keep its vertical scroll bar to its
+ * bottom after the realization of the resize if it is at its bottom before
+ * the resize.
+ */
+ @Override
+ public void setBounds(int x, int y, int width, int height)
+ {
+ synchronized (scrollToBottomRunnable)
+ {
+ JScrollBar verticalScrollBar = getVerticalScrollBar();
+
+ if (verticalScrollBar != null)
+ {
+ BoundedRangeModel verticalScrollBarModel
+ = verticalScrollBar.getModel();
+
+ if ((verticalScrollBarModel.getValue()
+ + verticalScrollBarModel.getExtent()
+ >= verticalScrollBarModel.getMaximum())
+ || !verticalScrollBar.isVisible())
+ scrollToBottomIsPending = true;
+ }
+ }
+
+ super.setBounds(x, y, width, height);
+ }
+
+ /**
+ * Initializes the editor by adding a header containing the date.
+ * TODO: remove if not used anymore
+ */
+// private void initEditor()
+// {
+// Element root = this.document.getDefaultRootElement();
+//
+// Date date = new Date(System.currentTimeMillis());
+//
+// String chatHeader = "<h1>" + GuiUtils.formatDate(date) + " " + "</h1>";
+//
+// try
+// {
+// this.document.insertAfterStart(root, chatHeader);
+// }
+// catch (BadLocationException e)
+// {
+// logger.error("Insert in the HTMLDocument failed.", e);
+// }
+// catch (IOException e)
+// {
+// logger.error("Insert in the HTMLDocument failed.", e);
+// }
+// }
+
+ /**
+ * Retrieves the contents of the sent message with the given ID.
+ *
+ * @param messageUID The ID of the message to retrieve.
+ * @return The contents of the message, or null if the message is not found.
+ */
+ public String getMessageContents(String messageUID)
+ {
+ Element root = document.getDefaultRootElement();
+ Element e = document.getElement(root, Attribute.ID, messageUID);
+ if (e == null)
+ {
+ logger.warn("Could not find message with ID" + messageUID);
+ return null;
+ }
+
+ int elemLen = e.getEndOffset() - e.getStartOffset();
+ String res = null;
+ try
+ {
+ res = document.getText(e.getStartOffset(), elemLen);
+ }
+ catch (BadLocationException exc)
+ {
+ logger.warn("Could not get message contents for message "
+ + "with ID" + messageUID, exc);
+ }
+ return res;
+ }
+
+ /**
+ * Creates a tag that shows the last edit time of a message, in the format
+ * (Edited at ...).
+ * If <tt>date < 0</tt>, returns an empty tag that serves as a placeholder
+ * for future corrections of this message.
+ *
+ * @param messageUID The ID of the edited message.
+ * @param date The date when the message was last edited, or -1 to generate
+ * an empty tag.
+ * @return The string representation of the tag.
+ */
+ private String generateEditedAtTag(String messageUID, long date)
+ {
+ StringBuilder res = new StringBuilder();
+ // Use a <cite /> tag here as most of the other inline tags (e.g. h1-7,
+ // b, i) cause different problems when used in setOuterHTML.
+ res.append("<cite id='");
+ res.append(messageUID);
+ res.append("-editedAt'> ");
+ if (date > 0)
+ {
+ res.append("&nbsp;");
+ String contents = GuiActivator.getResources().getI18NString(
+ "service.gui.EDITED_AT",
+ new String[] { GuiUtils.formatTime(date) }
+ );
+ res.append(contents);
+ }
+ res.append("</cite>");
+ return res.toString();
+ }
+
+ /**
+ * Processes the message given by the parameters.
+ *
+ * @param chatMessage the message
+ * @param keyword a substring of <tt>chatMessage</tt> to be highlighted upon
+ * display of <tt>chatMessage</tt> in the UI
+ * @return the processed message
+ */
+ public String processMessage(ChatMessage chatMessage, String keyword)
+ {
+ String contactName = chatMessage.getContactName();
+ String contactDisplayName = chatMessage.getContactDisplayName();
+ if (contactDisplayName == null
+ || contactDisplayName.trim().length() <= 0)
+ contactDisplayName = contactName;
+
+ String contentType = chatMessage.getContentType();
+ long date = chatMessage.getDate();
+ String messageType = chatMessage.getMessageType();
+ String messageTitle = chatMessage.getMessageTitle();
+ String message = chatMessage.getMessage();
+ String messageUID = chatMessage.getMessageUID();
+
+ String msgID = "message";
+ String msgHeaderID = "messageHeader";
+ String chatString = "";
+ String endHeaderTag = "";
+ String dateString = getDateString(date);
+ String idAttr = messageUID == null ? "" : " id='" + messageUID + "'";
+ String dateAttr = " date='" + date + "'";
+ String editedAtTag = generateEditedAtTag(messageUID, -1);
+
+ String startHistoryDivTag
+ = "<DIV identifier=\"" + msgID + "\" style=\"color:#707070;\">";
+ String startSystemDivTag
+ = "<DIV identifier=\"systemMessage\" style=\"color:#627EB7;\">";
+ String endDivTag = "</DIV>";
+
+ String startPlainTextTag;
+ String endPlainTextTag;
+
+ if (HTML_CONTENT_TYPE.equals(contentType))
+ {
+ startPlainTextTag = "";
+ endPlainTextTag = "";
+ }
+ else
+ {
+ startPlainTextTag = START_PLAINTEXT_TAG;
+ endPlainTextTag = END_PLAINTEXT_TAG;
+ }
+
+ if (messageType.equals(Chat.INCOMING_MESSAGE))
+ {
+ this.lastIncomingMsgTimestamp = System.currentTimeMillis();
+
+ StringBuffer headerBuffer = new StringBuffer();
+
+ headerBuffer.append("<h2 identifier=\"" + msgHeaderID + "\"");
+ headerBuffer.append(dateAttr + ">");
+ headerBuffer.append("<a style=\"color:#488fe7;");
+ headerBuffer.append("font-weight:bold;");
+ headerBuffer.append("text-decoration:none;\" ");
+ headerBuffer.append("href=\"" + contactName + "\">");
+ headerBuffer.append(dateString + contactDisplayName + " at "
+ + GuiUtils.formatTime(date) + editedAtTag);
+ headerBuffer.append("</a></h2>");
+
+ chatString = createIncomingMessageTag(msgID + "\"" + idAttr,
+ headerBuffer.toString(),
+ startPlainTextTag
+ + formatMessage(message, contentType, keyword)
+ + endPlainTextTag);
+System.out.println("CHAT STRING OSHTE TUUUUUK=======" + chatString);
+// chatString = "<h2 identifier=\"" + msgHeaderID + "\""
+// + " date=\"" + date + "\">"
+// + "<a style=\"color:#488fe7;"
+// + "font-weight:bold;"
+// + "text-decoration:none;\" "
+// + "href=\"" + contactName + "\">";
+//
+// endHeaderTag = "</a></h2>";
+
+// String startDivTag = "<DIV identifier=\"" + msgID
+// + "\" style=\""+ createIncomingMessageStyle()+"\">";
+//
+// chatString
+// += dateString + contactDisplayName + " at "
+// + GuiUtils.formatTime(date)
+// + endHeaderTag + startDivTag + startPlainTextTag
+// + formatMessage(message, contentType, keyword)
+// + endPlainTextTag + endDivTag;
+
+ }
+ else if (messageType.equals(Chat.SMS_MESSAGE))
+ {
+ chatString = "<h2 identifier=\""
+ + msgHeaderID
+ + "\" date=\""
+ + date + "\">";
+
+ endHeaderTag = "</h2>";
+
+ String startDivTag = "<DIV identifier=\"" + msgID
+ + "\" style=\""+ createSmsMessageStyle()+"\">";
+
+ chatString
+ += "SMS: " + dateString + contactName + " at "
+ + GuiUtils.formatTime(date) + endHeaderTag + startDivTag
+ + startPlainTextTag
+ + formatMessage(message, contentType, keyword)
+ + endPlainTextTag + endDivTag;
+ }
+ else if (messageType.equals(Chat.OUTGOING_MESSAGE))
+ {
+ chatString = "<h3 identifier=\"" + msgHeaderID + "\""
+ + dateAttr + ">"
+ + "<a style=\"color:#6a6868;"
+ + "font-weight:bold;"
+ + "text-decoration:none;\" "
+ + "href=\"" + contactName + "\">";
+
+ endHeaderTag = "</a></h3>";
+
+ String startDivTag = "<DIV identifier=\"" + msgID
+ + "\" style=\""+ createOutgoingMessageStyle()+"\">";
+
+ chatString
+ += dateString + contactDisplayName + " at "
+ + GuiUtils.formatTime(date) + editedAtTag + endHeaderTag
+ + startDivTag + startPlainTextTag
+ + formatMessage(message, contentType, keyword)
+ + endPlainTextTag + endDivTag;
+ }
+ else if (messageType.equals(Chat.STATUS_MESSAGE))
+ {
+ chatString = "<h4 identifier=\"statusMessage\" date=\""
+ + date + "\">";
+ endHeaderTag = "</h4>";
+
+ chatString
+ += GuiUtils.formatTime(date) + " " + contactName + " " + message
+ + endHeaderTag;
+ }
+ else if (messageType.equals(Chat.ACTION_MESSAGE))
+ {
+ chatString = "<p identifier=\"actionMessage\" date=\""
+ + date + "\">";
+ endHeaderTag = "</p>";
+
+ chatString += "* " + GuiUtils.formatTime(date)
+ + " " + contactName + " "
+ + message
+ + endHeaderTag;
+ }
+ else if (messageType.equals(Chat.SYSTEM_MESSAGE))
+ {
+ chatString
+ += startSystemDivTag + startPlainTextTag
+ + formatMessage(message, contentType, keyword)
+ + endPlainTextTag + endDivTag;
+ }
+ else if (messageType.equals(Chat.ERROR_MESSAGE))
+ {
+ chatString = "<h6 identifier=\""
+ + msgHeaderID
+ + "\" date=\""
+ + date + "\">";
+
+ endHeaderTag = "</h6>";
+
+ String errorIcon = "<IMG SRC='"
+ + ImageLoader.getImageUri(ImageLoader.EXCLAMATION_MARK)
+ + "' </IMG>";
+
+ chatString += errorIcon
+ + messageTitle
+ + endHeaderTag + "<h5>" + message + "</h5>";
+ }
+ else if (messageType.equals(Chat.HISTORY_INCOMING_MESSAGE))
+ {
+ chatString = "<h2 identifier=\"" + msgHeaderID + "\""
+ + dateAttr + ">"
+ + "<a style=\"color:#488fe7;"
+ + "font-weight:bold;"
+ + "text-decoration:none;\" "
+ + "href=\"" + contactName + "\">";
+
+ endHeaderTag = "</a></h2>";
+
+ chatString
+ += dateString + contactDisplayName
+ + " at " + GuiUtils.formatTime(date) + endHeaderTag
+ + editedAtTag + startHistoryDivTag + startPlainTextTag
+ + formatMessage(message, contentType, keyword)
+ + endPlainTextTag + endDivTag;
+ }
+ else if (messageType.equals(Chat.HISTORY_OUTGOING_MESSAGE))
+ {
+ chatString = "<h3 identifier=\"" + msgHeaderID + "\""
+ + dateAttr + ">"
+ + "<a style=\"color:#6a6868;"
+ + "font-weight:bold;"
+ + "text-decoration:none;\" "
+ + "href=\"" + contactName + "\">";
+
+ endHeaderTag = "</h3>";
+
+ chatString
+ += dateString
+ + contactDisplayName + " at " + GuiUtils.formatTime(date)
+ + editedAtTag + endHeaderTag
+ + startHistoryDivTag + startPlainTextTag
+ + formatMessage(message, contentType, keyword)
+ + endPlainTextTag + endDivTag;
+ }
+
+ return chatString;
+ }
+
+ /**
+ * Processes the message given by the parameters.
+ *
+ * @param chatMessage the message.
+ * @return the formatted message
+ */
+ public String processMessage(ChatMessage chatMessage)
+ {
+ return processMessage(chatMessage, null);
+ }
+
+ /**
+ * Replaces the contents of the message with ID of the corrected message
+ * specified in chatMessage, with this message.
+ *
+ * @param chatMessage A <tt>ChatMessage</tt> that contains all the required
+ * information to correct the old message.
+ */
+ public void correctMessage(ChatMessage chatMessage)
+ {
+ String correctedUID = chatMessage.getCorrectedMessageUID();
+ Element root = document.getDefaultRootElement();
+ Element e = document.getElement(root, Attribute.ID, correctedUID);
+ if (e == null)
+ {
+ logger.warn("Could not find message with ID " + correctedUID);
+ return;
+ }
+ int len = e.getEndOffset() - e.getStartOffset();
+
+ StringBuilder newContents = new StringBuilder();
+ String bgColor = GuiActivator.getResources().getColorString(
+ "service.gui.CHAT_EDIT_MESSAGE_BACKGROUND");
+ newContents.append("<div identifier='message' id='");
+ newContents.append(chatMessage.getMessageUID());
+ newContents.append("' bgcolor='");
+ newContents.append(bgColor);
+ newContents.append("'>");
+ if (chatMessage.getContentType().equals(TEXT_CONTENT_TYPE))
+ {
+ newContents.append(START_PLAINTEXT_TAG);
+ newContents.append(chatMessage.getMessage());
+ newContents.append(END_PLAINTEXT_TAG);
+ }
+ else
+ {
+ newContents.append(chatMessage.getMessage());
+ }
+ newContents.append("</div>");
+
+ Element header = document.getElement(root, Attribute.ID,
+ correctedUID + "-editedAt");
+
+ try
+ {
+ if (header != null)
+ {
+ String newHeaderContents = generateEditedAtTag(
+ chatMessage.getMessageUID(), chatMessage.getDate());
+ document.setOuterHTML(header, newHeaderContents);
+ }
+ document.setOuterHTML(e, newContents.toString());
+ }
+ catch (BadLocationException ex)
+ {
+ logger.error("Could not replace chat message", ex);
+ }
+ catch (IOException ex)
+ {
+ logger.error("Could not replace chat message", ex);
+ }
+ }
+
+ /**
+ * Appends the given string at the end of the contained in this panel
+ * document.
+ *
+ * @param chatString the string to append
+ */
+ public void appendMessageToEnd(String chatString, String contentType)
+ {
+ synchronized (scrollToBottomRunnable)
+ {
+ Element root = document.getDefaultRootElement();
+
+// Need to call explicitly scrollToBottom, because for some
+// reason the componentResized event isn't fired every time we
+// add text.
+// Replaced by the code on line: 573.
+//
+// scrollToBottomIsPending = true;
+System.out.println("CHAT STRING+=========" + chatString);
+ try
+ {
+ document
+ .insertAfterEnd(
+ root.getElement(root.getElementCount() - 1),
+ chatString);
+
+ // Need to call explicitly scrollToBottom, because for some
+ // reason the componentResized event isn't fired every time we
+ // add text.
+ SwingUtilities.invokeLater(scrollToBottomRunnable);
+ }
+ catch (BadLocationException e)
+ {
+ logger.error("Insert in the HTMLDocument failed.", e);
+ }
+ catch (IOException e)
+ {
+ logger.error("Insert in the HTMLDocument failed.", e);
+ }
+ if (!isHistory)
+ ensureDocumentSize();
+
+ // Process replacements.
+ final Element elem;
+ /*
+ * Check to make sure element isn't the first element in the HTML
+ * document.
+ */
+ if (!(root.getElementCount() < 2))
+ {
+ elem = root.getElement(root.getElementCount() - 2);
+ }
+ else
+ elem = root.getElement(1);
+
+ /*
+ * Replacements will be processed only if it is enabled in the
+ * property
+ */
+ if (GuiActivator.getConfigurationService().getBoolean(
+ ReplacementProperty.REPLACEMENT_ENABLE, true)
+ || GuiActivator.getConfigurationService().getBoolean(
+ ReplacementProperty.getPropertyName("SMILEY"), true))
+ {
+ processReplacement(elem, chatString, contentType);
+ }
+ }
+ }
+
+ /**
+ * Formats the given message. Processes the messages and replaces links to
+ * video/image sources with their previews or any other substitution. Spawns
+ * a separate thread for replacement.
+ *
+ * @param elem the element in the HTML Document.
+ * @param chatString the message.
+ */
+ private void processReplacement(final Element elem,
+ final String chatString,
+ final String contentType)
+ {
+ final String chatFinal = chatString;
+
+ SwingWorker worker = new SwingWorker()
+ {
+ public Object construct() throws Exception
+ {
+ String temp = "", msgStore = chatFinal;
+
+ boolean isEnabled
+ = GuiActivator.getConfigurationService().getBoolean(
+ ReplacementProperty.REPLACEMENT_ENABLE, true);
+
+ Map<String, ReplacementService> listSources
+ = GuiActivator.getReplacementSources();
+
+ Iterator<Entry<String, ReplacementService>> entrySetIter
+ = listSources.entrySet().iterator();
+
+ for (int i = 0; i < listSources.size(); i++)
+ {
+ Map.Entry<String, ReplacementService> entry
+ = entrySetIter.next();
+
+ ReplacementService source = entry.getValue();
+
+ boolean isSmiley
+ = source instanceof SmiliesReplacementService;
+
+ if (!(GuiActivator.getConfigurationService().getBoolean(
+ ReplacementProperty.getPropertyName(source
+ .getSourceName()), true) && (isEnabled || isSmiley)))
+ continue;
+
+ String sourcePattern = source.getPattern();
+ Pattern p = Pattern.compile(sourcePattern,
+ Pattern.CASE_INSENSITIVE | Pattern.DOTALL);
+
+ Matcher m = p.matcher(msgStore);
+
+ String startPlainTextTag = "";
+ String endPlainTextTag = "";
+
+ if (!HTML_CONTENT_TYPE.equals(contentType))
+ {
+ startPlainTextTag = START_PLAINTEXT_TAG;
+ endPlainTextTag = END_PLAINTEXT_TAG;
+ }
+
+ int count = 0, startPos = 0;
+ StringBuffer msgBuff = new StringBuffer();
+
+ while (m.find())
+ {
+ count++;
+ msgBuff.append(msgStore.substring(startPos, m.start()));
+ startPos = m.end();
+
+ temp = source.getReplacement(m.group());
+
+ if(!temp.equals(m.group(0)) || source.getSourceName()
+ .equals("DIRECTIMAGE"))
+ {
+ if(isSmiley)
+ {
+ msgBuff.append(endPlainTextTag);
+ msgBuff.append("<IMG SRC=\"");
+ }
+ else
+ {
+ msgBuff.append(
+ "<IMG HEIGHT=\"90\" WIDTH=\"120\" SRC=\"");
+ }
+
+ msgBuff.append(temp);
+ msgBuff.append("\" BORDER=\"0\" ALT=\"");
+ msgBuff.append(m.group(0));
+ msgBuff.append("\"></IMG>");
+
+ if(isSmiley)
+ msgBuff.append(startPlainTextTag);
+ }
+ else
+ {
+ msgBuff.append(
+ msgStore.substring(m.start(), m.end()));
+ }
+ }
+
+ msgBuff.append(msgStore.substring(startPos));
+
+ /*
+ * replace the msgStore variable with the current replaced
+ * message before next iteration
+ */
+ if (!msgBuff.toString().equals(msgStore))
+ {
+ msgStore = msgBuff.toString();
+ }
+ }
+
+ if (!msgStore.equals(chatFinal))
+ {
+ synchronized (scrollToBottomRunnable)
+ {
+ scrollToBottomIsPending = true;
+ document.setOuterHTML(elem, msgStore.toString()
+ .substring(msgStore.indexOf("<DIV")));
+ }
+ }
+ return "";
+ }
+ };
+ worker.start();
+ }
+
+ /**
+ * Ensures that the document won't become too big. When the document reaches
+ * a certain size the first message in the page is removed.
+ */
+ private void ensureDocumentSize()
+ {
+ if (document.getLength() > Chat.CHAT_BUFFER_SIZE)
+ {
+ int msgElementCount = 0;
+
+ Element firstMsgElement = null;
+
+ int firstMsgIndex = 0;
+
+ Element rootElement = this.document.getDefaultRootElement();
+ // Count how many messages we have in the document.
+ for (int i = 0; i < rootElement.getElementCount(); i++)
+ {
+ String idAttr = (String) rootElement.getElement(i)
+ .getAttributes().getAttribute("identifier");
+
+ if(idAttr != null
+ && (idAttr.equals("message")
+ || idAttr.equals("statusMessage")
+ || idAttr.equals("systemMessage")))
+ {
+ if(firstMsgElement == null)
+ {
+ firstMsgElement = rootElement.getElement(i);
+ firstMsgIndex = i;
+ }
+
+ msgElementCount++;
+ }
+ }
+
+ // If we doesn't have any known elements in the document or if we
+ // have only one long message we don't want to remove it.
+ if(firstMsgElement == null || msgElementCount < 2)
+ return;
+
+ try
+ {
+ // Remove the header of the message if such exists.
+ if(firstMsgIndex > 0)
+ {
+ Element headerElement = rootElement.getElement(firstMsgIndex - 1);
+
+ String idAttr = (String) headerElement
+ .getAttributes().getAttribute("identifier");
+
+ if(idAttr != null && idAttr.equals("messageHeader"))
+ {
+ this.document.remove(headerElement.getStartOffset(),
+ headerElement.getEndOffset()
+ - headerElement.getStartOffset());
+ }
+ }
+
+ // Remove the message itself.
+ this.document.remove(firstMsgElement.getStartOffset(),
+ firstMsgElement.getEndOffset()
+ - firstMsgElement.getStartOffset());
+ }
+ catch (BadLocationException e)
+ {
+ logger.error("Error removing messages from chat: ", e);
+ }
+ }
+ }
+
+ /**
+ * Highlights keywords searched in the history.
+ *
+ * @param message the source message
+ * @param contentType the content type
+ * @param keyword the searched keyword
+ * @return the formatted message
+ */
+ private String processKeyword( String message,
+ String contentType,
+ String keyword)
+ {
+ String startPlainTextTag;
+ String endPlainTextTag;
+
+ if (HTML_CONTENT_TYPE.equals(contentType))
+ {
+ startPlainTextTag = "";
+ endPlainTextTag = "";
+ }
+ else
+ {
+ startPlainTextTag = START_PLAINTEXT_TAG;
+ endPlainTextTag = END_PLAINTEXT_TAG;
+ }
+
+ Matcher m
+ = Pattern.compile(Pattern.quote(keyword), Pattern.CASE_INSENSITIVE)
+ .matcher(message);
+ StringBuffer msgBuffer = new StringBuffer();
+ int prevEnd = 0;
+
+ while (m.find())
+ {
+ msgBuffer.append(message.substring(prevEnd, m.start()));
+ prevEnd = m.end();
+
+ String keywordMatch = m.group().trim();
+
+ msgBuffer.append(endPlainTextTag);
+ msgBuffer.append("<b>");
+ msgBuffer.append(keywordMatch);
+ msgBuffer.append("</b>");
+ msgBuffer.append(startPlainTextTag);
+ }
+
+ /*
+ * If the keyword didn't match, let the outside world be able to
+ * discover it.
+ */
+ if (prevEnd == 0)
+ return message;
+
+ msgBuffer.append(message.substring(prevEnd));
+ return msgBuffer.toString();
+ }
+
+ /**
+ * Formats the given message. Processes all smiley chars, new lines and
+ * links.
+ *
+ * @param message the message to be formatted
+ * @param contentType the content type of the message to be formatted
+ * @param keyword the word to be highlighted
+ * @return the formatted message
+ */
+ private String formatMessage(String message,
+ String contentType,
+ String keyword)
+ {
+ // If the message content type is HTML we won't process links and
+ // new lines, but only the smileys.
+ if (!HTML_CONTENT_TYPE.equals(contentType))
+ {
+
+ /*
+ * We disallow HTML in plain-text messages. But processKeyword
+ * introduces HTML. So we'll allow HTML if processKeyword has
+ * introduced it in order to not break highlighting.
+ */
+ boolean processHTMLChars;
+
+ if ((keyword != null) && (keyword.length() != 0))
+ {
+ String messageWithProcessedKeyword
+ = processKeyword(message, contentType, keyword);
+
+ /*
+ * The same String instance will be returned if there was no
+ * keyword match. Calling #equals() is expensive so == is
+ * intentional.
+ */
+ processHTMLChars = (messageWithProcessedKeyword == message);
+ message = messageWithProcessedKeyword;
+ }
+ else
+ processHTMLChars = true;
+
+ message
+ = processNewLines(
+ processLinksAndHTMLChars(message, processHTMLChars));
+ }
+ // If the message content is HTML, we process br and img tags.
+ else
+ {
+ if ((keyword != null) && (keyword.length() != 0))
+ message = processKeyword(message, contentType, keyword);
+ message = processImgTags(processBrTags(message));
+ }
+
+ return message;
+ }
+
+ /**
+ * Formats all links in a given message and optionally escapes special HTML
+ * characters such as &lt;, &gt;, &amp; and &quot; in order to prevent HTML
+ * injection in plain-text messages such as writing
+ * <code>&lt;/PLAINTEXT&gt;</code>, HTML which is going to be rendered as
+ * such and <code>&lt;PLAINTEXT&gt;</code>. The two procedures are carried
+ * out in one call in order to not break URLs which contain special HTML
+ * characters such as &amp;.
+ *
+ * @param message The source message string.
+ * @param processHTMLChars <tt>true</tt> to escape the special HTML chars;
+ * otherwise, <tt>false</tt>
+ * @return The message string with properly formatted links.
+ */
+ private String processLinksAndHTMLChars(String message,
+ boolean processHTMLChars)
+ {
+ Matcher m = URL_PATTERN.matcher(message);
+ StringBuffer msgBuffer = new StringBuffer();
+ int prevEnd = 0;
+
+ while (m.find())
+ {
+ String fromPrevEndToStart = message.substring(prevEnd, m.start());
+
+ if (processHTMLChars)
+ fromPrevEndToStart = processHTMLChars(fromPrevEndToStart);
+ msgBuffer.append(fromPrevEndToStart);
+ prevEnd = m.end();
+
+ String url = m.group().trim();
+
+ msgBuffer.append(END_PLAINTEXT_TAG);
+ msgBuffer.append("<A href=\"");
+ if (url.startsWith("www"))
+ msgBuffer.append("http://");
+ msgBuffer.append(url);
+ msgBuffer.append("\">");
+ msgBuffer.append(url);
+ msgBuffer.append("</A>");
+ msgBuffer.append(START_PLAINTEXT_TAG);
+ }
+
+ String fromPrevEndToEnd = message.substring(prevEnd);
+
+ if (processHTMLChars)
+ fromPrevEndToEnd = processHTMLChars(fromPrevEndToEnd);
+ msgBuffer.append(fromPrevEndToEnd);
+
+ return msgBuffer.toString();
+ }
+
+ /**
+ * Escapes special HTML characters such as &lt;, &gt;, &amp; and &quot; in
+ * the specified message.
+ *
+ * @param message the message to be processed
+ * @return the processed message with escaped special HTML characters
+ */
+ private String processHTMLChars(String message)
+ {
+ return
+ message
+ .replace("&", "&amp;")
+ .replace("<", "&lt;")
+ .replace(">", "&gt;")
+ .replace("\"", "&quot;");
+ }
+
+ /**
+ * Formats message new lines.
+ *
+ * @param message The source message string.
+ * @return The message string with properly formatted new lines.
+ */
+ private String processNewLines(String message)
+ {
+
+ /*
+ * <br> tags are needed to visualize a new line in the html format, but
+ * when copied to the clipboard they are exported to the plain text
+ * format as ' ' and not as '\n'.
+ *
+ * See bug N4988885:
+ * http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4988885
+ *
+ * To fix this we need "&#10;" - the HTML-Code for ASCII-Character No.10
+ * (Line feed).
+ */
+ return
+ message
+ .replaceAll(
+ "\n",
+ END_PLAINTEXT_TAG + "<BR/>&#10;" + START_PLAINTEXT_TAG);
+ }
+
+ /**
+ * Opens a link in the default browser when clicked and shows link url in a
+ * popup on mouseover.
+ *
+ * @param e The HyperlinkEvent.
+ */
+ public void hyperlinkUpdate(HyperlinkEvent e)
+ {
+ if (e.getEventType() == HyperlinkEvent.EventType.ENTERED)
+ {
+ String href = e.getDescription();
+
+ this.currentHref = href;
+ }
+ else if (e.getEventType() == HyperlinkEvent.EventType.EXITED)
+ {
+ this.currentHref = "";
+ }
+ }
+
+ /**
+ * Returns the text pane of this conversation panel.
+ *
+ * @return The text pane of this conversation panel.
+ */
+ public JTextPane getChatTextPane()
+ {
+ return chatTextPane;
+ }
+
+ /**
+ * Returns the time of the last received message.
+ *
+ * @return The time of the last received message.
+ */
+ public long getLastIncomingMsgTimestamp()
+ {
+ return lastIncomingMsgTimestamp;
+ }
+
+ /**
+ * When a right button click is performed in the editor pane, a popup menu
+ * is opened.
+ * In case of the Scheme being internal, it won't open the Browser but
+ * instead it will trigger the forwarded action.
+ *
+ * @param e The MouseEvent.
+ */
+ public void mouseClicked(MouseEvent e)
+ {
+ Point p = e.getPoint();
+ SwingUtilities.convertPointToScreen(p, e.getComponent());
+
+ if ((e.getModifiers() & InputEvent.BUTTON3_MASK) != 0
+ || (e.isControlDown() && !e.isMetaDown()))
+ {
+ openContextMenu(p);
+ }
+ else if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0
+ && currentHref != null && currentHref.length() != 0)
+ {
+ URI uri;
+ try
+ {
+ uri = new URI(currentHref);
+ }
+ catch (URISyntaxException e1)
+ {
+ logger.error("Invalid URL", e1);
+ return;
+ }
+ if(uri.getScheme().equals("jitsi"))
+ {
+ for(ChatLinkClickedListener l:chatLinkClickedListeners)
+ {
+ l.chatLinkClicked(uri);
+ }
+ }
+ else
+ GuiActivator.getBrowserLauncher().openURL(currentHref);
+
+ // after opening the link remove the currentHref to avoid
+ // clicking on the window to gain focus to open the link again
+ this.currentHref = "";
+ }
+ }
+
+ /**
+ * Opens this panel context menu at the given point.
+ *
+ * @param p the point where to position the left-top cornet of the context
+ * menu
+ */
+ private void openContextMenu(Point p)
+ {
+ if (currentHref != null && currentHref.length() != 0
+ && !currentHref.startsWith("jitsi://"))
+ {
+ rightButtonMenu.insert(openLinkItem, 0);
+ rightButtonMenu.insert(copyLinkItem, 1);
+ rightButtonMenu.insert(copyLinkSeparator, 2);
+ }
+ else
+ {
+ rightButtonMenu.remove(openLinkItem);
+ rightButtonMenu.remove(copyLinkItem);
+ rightButtonMenu.remove(copyLinkSeparator);
+ }
+
+ if (chatTextPane.getSelectedText() != null)
+ {
+ rightButtonMenu.enableCopy();
+ }
+ else
+ {
+ rightButtonMenu.disableCopy();
+ }
+ rightButtonMenu.setInvoker(chatTextPane);
+ rightButtonMenu.setLocation(p.x, p.y);
+ rightButtonMenu.setVisible(true);
+ }
+
+ public void mousePressed(MouseEvent e) {}
+
+ public void mouseReleased(MouseEvent e) {}
+
+ public void mouseEntered(MouseEvent e) {}
+
+ public void mouseExited(MouseEvent e) {}
+
+ public void lostOwnership(Clipboard clipboard, Transferable contents) {}
+
+ /**
+ * Returns the chat container.
+ *
+ * @return the chat container
+ */
+ public ChatConversationContainer getChatContainer()
+ {
+ return chatContainer;
+ }
+
+ /**
+ * Copies the selected conversation panel content to the clipboard.
+ */
+ public void copyConversation()
+ {
+ this.chatTextPane.copy();
+ }
+
+ /**
+ * Creates new document and all the messages that will be processed in the
+ * future will be appended in it.
+ */
+ public void clear()
+ {
+ this.document = (HTMLDocument) editorKit.createDefaultDocument();
+ Constants.loadSimpleStyle(
+ document.getStyleSheet(), chatTextPane.getFont());
+ }
+
+ /**
+ * Sets the given document to the editor pane in this panel.
+ *
+ * @param document the document to set
+ */
+ public void setContent(HTMLDocument document)
+ {
+ synchronized (scrollToBottomRunnable)
+ {
+ scrollToBottomIsPending = true;
+
+ this.document = document;
+ chatTextPane.setDocument(this.document);
+ }
+ }
+
+ /**
+ * Sets the default document contained in this panel, created on init or
+ * when clear is invoked.
+ */
+ public void setDefaultContent()
+ {
+ setContent(document);
+ }
+
+ /**
+ * Returns the document contained in this panel.
+ *
+ * @return the document contained in this panel
+ */
+ public HTMLDocument getContent()
+ {
+ return (HTMLDocument) this.chatTextPane.getDocument();
+ }
+
+ /**
+ * Returns the right button popup menu.
+ *
+ * @return the right button popup menu
+ */
+ public ChatRightButtonMenu getRightButtonMenu()
+ {
+ return rightButtonMenu;
+ }
+
+ /**
+ * Returns the date of the first message in the current page.
+ *
+ * @return the date of the first message in the current page
+ */
+ public Date getPageFirstMsgTimestamp()
+ {
+ Element rootElement = this.document.getDefaultRootElement();
+
+ Element firstMessageElement = null;
+
+ for(int i = 0; i < rootElement.getElementCount(); i ++)
+ {
+ String idAttr = (String) rootElement.getElement(i)
+ .getAttributes().getAttribute("identifier");
+
+ if (idAttr != null && idAttr.equals("messageHeader"))
+ {
+ firstMessageElement = rootElement.getElement(i);
+ break;
+ }
+ }
+
+ if(firstMessageElement == null)
+ return new Date(Long.MAX_VALUE);
+
+ String dateObject = firstMessageElement
+ .getAttributes().getAttribute("date").toString();
+
+ return new Date(Long.parseLong(dateObject));
+ }
+
+ /**
+ * Returns the date of the last message in the current page.
+ *
+ * @return the date of the last message in the current page
+ */
+ public Date getPageLastMsgTimestamp()
+ {
+ Element rootElement = this.document.getDefaultRootElement();
+
+ Element lastMessageElement = null;
+
+ for(int i = rootElement.getElementCount() - 1; i >= 0; i --)
+ {
+ String idAttr = (String) rootElement.getElement(i)
+ .getAttributes().getAttribute("identifier");
+
+ if (idAttr != null && idAttr.equals("messageHeader"))
+ {
+ lastMessageElement = rootElement.getElement(i);
+ break;
+ }
+ }
+
+ if(lastMessageElement == null)
+ return new Date(0);
+
+ String dateObject = lastMessageElement
+ .getAttributes().getAttribute("date").toString();
+
+ return new Date(Long.parseLong(dateObject));
+ }
+
+ /**
+ * Formats HTML tags &lt;br/&gt; to &lt;br&gt; or &lt;BR/&gt; to &lt;BR&gt;.
+ * The reason of this function is that the ChatPanel does not support
+ * &lt;br /&gt; closing tags (XHTML syntax), thus we have to remove every
+ * slash from each &lt;br /&gt; tags.
+ * @param message The source message string.
+ * @return The message string with properly formatted &lt;br&gt; tags.
+ */
+ private String processBrTags(String message)
+ {
+ // The resulting message after being processed by this function.
+ StringBuffer processedMessage = new StringBuffer();
+
+ // Compile the regex to match something like <br .. /> or <BR .. />.
+ // This regex is case sensitive and keeps the style or other
+ // attributes of the <br> tag.
+ Matcher m
+ = Pattern.compile("<\\s*[bB][rR](.*?)(/\\s*>)").matcher(message);
+ int start = 0;
+
+ // while we find some <br /> closing tags with a slash inside.
+ while(m.find())
+ {
+ // First, we have to copy all the message preceding the <br> tag.
+ processedMessage.append(message.substring(start, m.start()));
+ // Then, we find the position of the slash inside the tag.
+ int slash_index = m.group().lastIndexOf("/");
+ // We copy the <br> tag till the slash exclude.
+ processedMessage.append(m.group().substring(0, slash_index));
+ // We copy all the end of the tag following the slash exclude.
+ processedMessage.append(m.group().substring(slash_index+1));
+ start = m.end();
+ }
+ // Finally, we have to add the end of the message following the last
+ // <br> tag, or the whole message if there is no <br> tag.
+ processedMessage.append(message.substring(start));
+
+ return processedMessage.toString();
+ }
+
+ /**
+ * Formats HTML tags &lt;img ... /&gt; to &lt; img ... &gt;&lt;/img&gt; or
+ * &lt;IMG ... /&gt; to &lt;IMG&gt;&lt;/IMG&gt;.
+ * The reason of this function is that the ChatPanel does not support
+ * &lt;img /&gt; tags (XHTML syntax).
+ * Thus, we remove every slash from each &lt;img /&gt; and close it with a
+ * separate closing tag.
+ * @param message The source message string.
+ * @return The message string with properly formatted &lt;img&gt; tags.
+ */
+ private String processImgTags(String message)
+ {
+ // The resulting message after being processed by this function.
+ StringBuffer processedMessage = new StringBuffer();
+
+ // Compile the regex to match something like <img ... /> or
+ // <IMG ... />. This regex is case sensitive and keeps the style,
+ // src or other attributes of the <img> tag.
+ Pattern p = Pattern.compile("<\\s*[iI][mM][gG](.*?)(/\\s*>)");
+ Matcher m = p.matcher(message);
+ int slash_index;
+ int start = 0;
+
+ // while we find some <img /> self-closing tags with a slash inside.
+ while(m.find()){
+ // First, we have to copy all the message preceding the <img> tag.
+ processedMessage.append(message.substring(start, m.start()));
+ // Then, we find the position of the slash inside the tag.
+ slash_index = m.group().lastIndexOf("/");
+ // We copy the <img> tag till the slash exclude.
+ processedMessage.append(m.group().substring(0, slash_index));
+ // We copy all the end of the tag following the slash exclude.
+ processedMessage.append(m.group().substring(slash_index+1));
+ // We close the tag with a separate closing tag.
+ processedMessage.append("</img>");
+ start = m.end();
+ }
+ // Finally, we have to add the end of the message following the last
+ // <img> tag, or the whole message if there is no <img> tag.
+ processedMessage.append(message.substring(start));
+
+ return processedMessage.toString();
+ }
+
+ /**
+ * Extend Editor pane to add URL tooltips.
+ */
+ private class MyTextPane
+ extends JTextPane
+ {
+ /**
+ * Returns the string to be used as the tooltip for <i>event</i>.
+ *
+ * @param event the <tt>MouseEvent</tt>
+ * @return the string to be used as the tooltip for <i>event</i>.
+ */
+ @Override
+ public String getToolTipText(MouseEvent event)
+ {
+ return
+ ((currentHref != null) && (currentHref.length() != 0))
+ ? currentHref
+ : null;
+ }
+ }
+
+ /**
+ * Adds a custom component at the end of the conversation.
+ *
+ * @param component the component to add at the end of the conversation.
+ */
+ public void addComponent(ChatConversationComponent component)
+ {
+ synchronized (scrollToBottomRunnable)
+ {
+ StyleSheet styleSheet = document.getStyleSheet();
+ Style style
+ = styleSheet
+ .addStyle(
+ StyleConstants.ComponentElementName,
+ styleSheet.getStyle("body"));
+
+ // The image must first be wrapped in a style
+ style
+ .addAttribute(
+ AbstractDocument.ElementNameAttribute,
+ StyleConstants.ComponentElementName);
+
+ TransparentPanel wrapPanel
+ = new TransparentPanel(new BorderLayout());
+
+ wrapPanel.add(component, BorderLayout.NORTH);
+
+ style
+ .addAttribute(StyleConstants.ComponentAttribute, wrapPanel);
+ style.addAttribute("identifier", "messageHeader");
+ style.addAttribute("date", component.getDate().getTime());
+
+ scrollToBottomIsPending = true;
+
+ // Insert the component style at the end of the text
+ try
+ {
+ document
+ .insertString(document.getLength(), "ignored text", style);
+ }
+ catch (BadLocationException e)
+ {
+ logger.error("Insert in the HTMLDocument failed.", e);
+ }
+ }
+ }
+
+ /**
+ * Registers a new link click listener.
+ *
+ * @param listener the object that should be notified when an internal
+ * link was clicked.
+ */
+ public void addChatLinkClickedListener(ChatLinkClickedListener listener)
+ {
+ if(!chatLinkClickedListeners.contains(listener))
+ chatLinkClickedListeners.add(listener);
+ }
+
+ /**
+ * Remove a registered link click listener.
+ *
+ * @param listener a registered click listener to remove
+ */
+ public void removeChatLinkClickedListener(ChatLinkClickedListener listener)
+ {
+ chatLinkClickedListeners.remove(listener);
+ }
+
+ /**
+ * Returns the date string to show for the given date.
+ *
+ * @param date the date to format
+ * @return the date string to show for the given date
+ */
+ public static String getDateString(long date)
+ {
+ if (GuiUtils.compareDatesOnly(date, System.currentTimeMillis()) < 0)
+ {
+ StringBuffer dateStrBuf = new StringBuffer();
+
+ GuiUtils.formatDate(date, dateStrBuf);
+ dateStrBuf.append(" ");
+ return dateStrBuf.toString();
+ }
+
+ return "";
+ }
+
+ /**
+ * Reloads images.
+ */
+ public void loadSkin()
+ {
+ openLinkItem.setIcon(
+ new ImageIcon(ImageLoader.getImage(ImageLoader.BROWSER_ICON)));
+ copyLinkItem.setIcon(
+ new ImageIcon(ImageLoader.getImage(ImageLoader.COPY_ICON)));
+
+ getRightButtonMenu().loadSkin();
+ }
+
+ /**
+ * Highlights the string in multi user chat.
+ *
+ * @param message the message to process
+ * @param contentType the content type of the message
+ * @param keyWord the keyword to highlight
+ * @return the message string with the keyword highlighted
+ */
+ public String processChatRoomHighlight(String message, String contentType,
+ String keyWord)
+ {
+ return processKeyword(message, contentType, keyWord);
+ }
+
+ public String processMeCommand(ChatMessage chatMessage)
+ {
+ String contentType = chatMessage.getContentType();
+ String message = chatMessage.getMessage();
+
+ String msgID = "message";
+ String chatString = "";
+ String endHeaderTag = "";
+
+ String startDivTag = "<DIV identifier=\"" + msgID + "\">";
+ String endDivTag = "</DIV>";
+
+ String startPlainTextTag;
+ String endPlainTextTag;
+
+ if (HTML_CONTENT_TYPE.equals(contentType))
+ {
+ startPlainTextTag = "";
+ endPlainTextTag = "";
+ }
+ else
+ {
+ startPlainTextTag = START_PLAINTEXT_TAG;
+ endPlainTextTag = END_PLAINTEXT_TAG;
+ }
+
+ if (message.length() > 4 && message.substring(0, 4).equals("/me "))
+ {
+ chatString = startDivTag + "<B><I>";
+
+ endHeaderTag = "</I></B>" + endDivTag;
+
+ chatString +=
+
+ processHTMLChars("*** " + chatMessage.getContactName() + " "
+ + message.substring(4))
+ + endHeaderTag;
+
+ Map<String, ReplacementService> listSources =
+ GuiActivator.getReplacementSources();
+
+ Iterator<Entry<String, ReplacementService>> entrySetIter =
+ listSources.entrySet().iterator();
+ StringBuffer msgStore = new StringBuffer(chatString);
+
+ for (int i = 0; i < listSources.size(); i++)
+ {
+ Map.Entry<String, ReplacementService> entry =
+ entrySetIter.next();
+
+ ReplacementService source = entry.getValue();
+
+ boolean isSmiley = source instanceof SmiliesReplacementService;
+ if (isSmiley)
+ {
+ String sourcePattern = source.getPattern();
+ Pattern p =
+ Pattern.compile(sourcePattern, Pattern.CASE_INSENSITIVE
+ | Pattern.DOTALL);
+ Matcher m = p.matcher(msgStore);
+
+ StringBuffer msgTemp = new StringBuffer(chatString);
+
+ while (m.find())
+ {
+ msgTemp.insert(m.start(), startPlainTextTag);
+ msgTemp.insert(m.end() + startPlainTextTag.length(),
+ endPlainTextTag);
+
+ }
+ if (msgTemp.length() != msgStore.length())
+ msgStore = msgTemp;
+ }
+ }
+
+ return msgStore.toString();
+ }
+ else
+ return "";
+ }
+
+ private static String createIncomingMessageTag(
+ String messageID,
+ String incomingMessageHeader,
+ String incomingMessageParagraph)
+ {
+ StringBuffer messageBuff = new StringBuffer();
+
+// <div class="box">
+// <div class="topleft">
+// <div class="topright">
+// <div class="messageDiv">
+// <h3>Header</h3>
+// <p>Text</p>
+// </div>
+// </div>
+// </div>
+// <div class="bottomleft">
+// <div class="bottomright">
+// </div>
+// </div>
+// </div>
+
+ messageBuff.append("<div " + createBoxStyle() + ">");
+ messageBuff.append("<div " + createTopLeftStyle() + ">");
+ messageBuff.append("<div " + createTopRightStyle() + ">");
+ messageBuff.append("<div identifier=\"" + messageID
+ + "\" " + createMessageDivStyle() + ">");
+ messageBuff.append(incomingMessageHeader);
+ messageBuff.append(incomingMessageParagraph);
+ messageBuff.append("</div>");
+ messageBuff.append("</div>");
+ messageBuff.append("</div>");
+ messageBuff.append("<div " + createBottomLeftStyle() + ">");
+ messageBuff.append("<div " + createBottomRightStyle() + ">");
+ messageBuff.append("</div>");
+ messageBuff.append("</div>");
+ messageBuff.append("</div>");
+
+ return messageBuff.toString();
+ }
+
+ private static String createOutgoingMessageStyle()
+ {
+ StringBuffer styleBuff = new StringBuffer();
+
+ styleBuff.append("background-image:");
+ styleBuff.append("url('bundle://30.0:1/resources/images/impl/gui/lookandfeel/selectedTabMiddle.png');");
+ styleBuff.append("background-repeat:");
+ styleBuff.append("repeat-x;");
+
+ return styleBuff.toString();
+ }
+
+ private static String createSmsMessageStyle()
+ {
+ StringBuffer styleBuff = new StringBuffer();
+
+ styleBuff.append("background-image:");
+ styleBuff.append("url('bundle://30.0:1/resources/images/impl/gui/lookandfeel/tabRight.png');");
+ styleBuff.append("background-repeat:");
+ styleBuff.append("repeat-x;");
+
+ return styleBuff.toString();
+ }
+
+// .box {
+// width: 100%;
+// margin: 0px auto;
+// }
+ private static String createBoxStyle()
+ {
+ return "style=\"width: 100%;"
+ + " margin-top: 0px;"
+ + " margin-bottom: 0px;"
+ + " margin-left: auto;"
+ + " margin-right: auto;\"";
+ }
+
+// .box div.topleft {
+// display: block;
+// background: url("i/box-bg.png") top left no-repeat white;
+// padding: 0em 0em 0em 1.0em;
+// }
+ private static String createTopLeftStyle()
+ {
+ return "style=\"display: block;"
+ + " background-image: url('"+INCOMING_MESSAGE_IMAGE_PATH+"');"
+ + " background-repeat: no-repeat;"
+ + " background-position: top left;"
+ + " background-color: #FFFFFF;"
+ + " padding-top: 0em;"
+ + " padding-right: 0em;"
+ + " padding-bottom: 0em;"
+ + " padding-left: 0em;"
+ + "\"";
+ }
+
+// .box div.topright {
+// display: block;
+// background: url("i/box-bg.png") top right no-repeat white;
+// padding: 1.0em;
+// margin: -1.0em 0 0 1.0em;
+// }
+ private static String createTopRightStyle()
+ {
+ return "style=\"display: block;"
+ + " background-image: url('"+INCOMING_MESSAGE_IMAGE_PATH+"');"
+ + " background-repeat: no-repeat;"
+ + " background-position: top right;"
+ + " background-color: #FFFFFF;"
+ + " padding-top: 1em;"
+ + " padding-right: 1em;"
+ + " padding-bottom: 1em;"
+ + " padding-left: 1em;"
+ + " margin-top: -1.0em;"
+ + " margin-right: 0em;"
+ + " margin-bottom: 0em;"
+ + " margin-left: 1.0em;"
+ + "\"";
+ }
+
+// .box div.bottomleft {
+// display: block;
+// height: 55px;
+// margin-top: -1.0em;
+// background: url("i/box-bg.png") bottom left no-repeat white;
+// }
+ private static String createBottomLeftStyle()
+ {
+ return "style=\"display: block;"
+ + " height: 25px;"
+ + " margin-top: -1.0em;"
+ + " background-image: url('"+INCOMING_MESSAGE_IMAGE_PATH+"');"
+ + " background-repeat: no-repeat;"
+ + " background-position: bottom left;"
+ + " background-color: #FFFFFF;"
+ + "\"";
+ }
+
+// .box div.bottomright {
+// display: block;
+// background: url("i/box-bg.png") bottom right no-repeat white;
+// height: 55px;
+// margin-left: 3.0em;
+// }
+ private static String createBottomRightStyle()
+ {
+ return "style=\"display: block;"
+ + " height: 25px;"
+ + " margin-left: 3.0em;"
+ + " background-image: url('"+INCOMING_MESSAGE_IMAGE_PATH+"');"
+ + " background-repeat: no-repeat;"
+ + " background-position: bottom right;"
+ + " background-color: #FFFFFF;"
+ + "\"";
+ }
+
+// .box div.topright div {
+// margin-right: 1.5em;
+// }
+ private static String createMessageDivStyle()
+ {
+ return "style=\"margin-right: 1.5em;\"";
+ }
+
+// .box h4 {
+// margin-bottom: 0.4em;
+// background-image: none;
+// background-repeat: no-repeat;
+// margin:0;
+// padding:0;
+// text-align:center;
+// padding-bottom:15px;
+// }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/contactlist/MetaContactImpl.java b/src/net/java/sip/communicator/impl/contactlist/MetaContactImpl.java
index 8b1573d..81528e4 100644
--- a/src/net/java/sip/communicator/impl/contactlist/MetaContactImpl.java
+++ b/src/net/java/sip/communicator/impl/contactlist/MetaContactImpl.java
@@ -6,7 +6,6 @@
*/
package net.java.sip.communicator.impl.contactlist;
-import java.io.*;
import java.util.*;
import net.java.sip.communicator.service.contactlist.*;
@@ -14,8 +13,6 @@ import net.java.sip.communicator.service.contactlist.event.*;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.util.*;
-import org.jitsi.service.fileaccess.*;
-
/**
* A default implementation of the <code>MetaContact</code> interface.
*
@@ -94,34 +91,11 @@ public class MetaContactImpl
private Map<String, List<String>> details;
/**
- * The name (i.e. not the whole path) of the directory in which the avatar
- * files are to be cached for later reuse.
- */
- private final static String AVATAR_DIR = "avatarcache";
-
- /**
* Whether user has renamed this meta contact.
*/
private boolean isDisplayNameUserDefined = false;
/**
- * Characters and their replacement in created folder names
- */
- private final static String[][] ESCAPE_SEQUENCES = new String[][]
- {
- {"&", "&_amp"},
- {"/", "&_sl"},
- {"\\\\", "&_bs"}, // the char \
- {":", "&_co"},
- {"\\*", "&_as"}, // the char *
- {"\\?", "&_qm"}, // the char ?
- {"\"", "&_pa"}, // the char "
- {"<", "&_lt"},
- {">", "&_gt"},
- {"\\|", "&_pp"} // the char |
- };
-
- /**
* Creates new meta contact with a newly generated meta contact UID.
*/
MetaContactImpl()
@@ -636,16 +610,8 @@ public class MetaContactImpl
while (iter.hasNext())
{
Contact protoContact = iter.next();
- String avatarPath = AVATAR_DIR
- + File.separator
- + escapeSpecialCharacters(
- protoContact
- .getProtocolProvider()
- .getAccountID().getAccountUniqueID())
- + File.separator
- + escapeSpecialCharacters(protoContact.getAddress());
-
- cachedAvatar = getLocallyStoredAvatar(avatarPath);
+
+ cachedAvatar = AvatarCacheUtils.getCachedAvatar(protoContact);
/*
* Caching a zero-length avatar happens but such an avatar isn't
* very useful.
@@ -1103,136 +1069,7 @@ public class MetaContactImpl
this.cachedAvatar = avatarBytes;
this.avatarFileCacheAlreadyQueried = true;
- String avatarDirPath
- = AVATAR_DIR
- + File.separator
- + escapeSpecialCharacters(
- protoContact
- .getProtocolProvider()
- .getAccountID().getAccountUniqueID());
- String avatarFileName
- = escapeSpecialCharacters(protoContact.getAddress());
-
- File avatarDir = null;
- File avatarFile = null;
- try
- {
- FileAccessService fileAccessService
- = ContactlistActivator.getFileAccessService();
-
- avatarDir
- = fileAccessService.getPrivatePersistentDirectory(
- avatarDirPath);
- avatarFile
- = fileAccessService.getPrivatePersistentFile(
- avatarDirPath + File.separator + avatarFileName);
-
- if(!avatarFile.exists())
- {
- if (!avatarDir.exists() && !avatarDir.mkdirs())
- {
- throw
- new IOException(
- "Failed to create directory: "
- + avatarDir.getAbsolutePath());
- }
-
- if (!avatarFile.createNewFile())
- {
- throw
- new IOException(
- "Failed to create file"
- + avatarFile.getAbsolutePath());
- }
- }
-
- FileOutputStream fileOutStream = new FileOutputStream(avatarFile);
-
- try
- {
- fileOutStream.write(avatarBytes);
- fileOutStream.flush();
- }
- finally
- {
- fileOutStream.close();
- }
- }
- catch (Exception ex)
- {
- logger.error(
- "Failed to store avatar. dir =" + avatarDir
- + " file=" + avatarFile,
- ex);
- }
- }
-
- /**
- * Returns the avatar image corresponding to the given avatar path.
- *
- * @param avatarPath The path to the lovally stored avatar.
- * @return the avatar image corresponding to the given avatar path.
- */
- private byte[] getLocallyStoredAvatar(String avatarPath)
- {
- try
- {
- File avatarFile
- = ContactlistActivator
- .getFileAccessService()
- .getPrivatePersistentFile(avatarPath);
-
- if(avatarFile.exists())
- {
- FileInputStream avatarInputStream
- = new FileInputStream(avatarFile);
- byte[] bs = null;
-
- try
- {
- int available = avatarInputStream.available();
-
- if (available > 0)
- {
- bs = new byte[available];
- avatarInputStream.read(bs);
- }
- }
- finally
- {
- avatarInputStream.close();
- }
- if (bs != null)
- return bs;
- }
- }
- catch (Exception ex)
- {
- logger.error(
- "Could not read avatar image from file " + avatarPath,
- ex);
- }
- return null;
- }
-
- /**
- * Replaces the characters that we must escape used for the created
- * filename.
- *
- * @param id the <tt>String</tt> which is to have its characters escaped
- * @return a <tt>String</tt> derived from the specified <tt>id</tt> by
- * escaping characters
- */
- private String escapeSpecialCharacters(String id)
- {
- String resultId = id;
-
- for (int j = 0; j < ESCAPE_SEQUENCES.length; j++)
- {
- resultId = resultId.
- replaceAll(ESCAPE_SEQUENCES[j][0], ESCAPE_SEQUENCES[j][1]);
- }
- return resultId;
+ AvatarCacheUtils.cacheAvatar(protoContact, avatarBytes);
}
/**
diff --git a/src/net/java/sip/communicator/impl/gui/main/MainFrame.java b/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
index a0f2eb9..7bc1ea7 100644
--- a/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
+++ b/src/net/java/sip/communicator/impl/gui/main/MainFrame.java
@@ -276,7 +276,7 @@ public class MainFrame
this.setJMenuBar(menu);
TransparentPanel searchPanel
- = new TransparentPanel(new BorderLayout(2, 0));
+ = new TransparentPanel(new BorderLayout(5, 0));
searchPanel.add(searchField);
searchPanel.add(new DialPadButton(), BorderLayout.WEST);
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/AbstractCallToggleButton.java b/src/net/java/sip/communicator/impl/gui/main/call/AbstractCallToggleButton.java
index 7958d68..0c67e0b 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/AbstractCallToggleButton.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/AbstractCallToggleButton.java
@@ -37,17 +37,17 @@ public abstract class AbstractCallToggleButton
/**
* The background image.
*/
- protected ImageID bgImage;
+ protected ImageID bgImageID;
/**
* The rollover image
*/
- protected ImageID bgRolloverImage;
+ protected ImageID bgRolloverImageID;
/**
* The pressed image.
*/
- protected ImageID pressedImage;
+ protected ImageID pressedImageID;
/**
* The icon image.
@@ -136,27 +136,17 @@ public abstract class AbstractCallToggleButton
this.fullScreen = fullScreen;
this.settingsPanel = settingsPanel;
- if (fullScreen)
+ if(settingsPanel)
{
- bgImage = ImageLoader.FULL_SCREEN_BUTTON_BG;
- bgRolloverImage = ImageLoader.FULL_SCREEN_BUTTON_BG;
- pressedImage = ImageLoader.FULL_SCREEN_BUTTON_BG_PRESSED;
+ bgRolloverImageID = ImageLoader.CALL_SETTING_BUTTON_BG;
+ pressedImageID = ImageLoader.CALL_SETTING_BUTTON_PRESSED_BG;
}
else
{
- if(settingsPanel)
- {
- bgImage = ImageLoader.CALL_SETTING_BUTTON_BG;
- bgRolloverImage = ImageLoader.CALL_SETTING_BUTTON_BG;
- pressedImage = ImageLoader.CALL_SETTING_BUTTON_PRESSED_BG;
- }
- else
- {
- bgImage = ImageLoader.SOUND_SETTING_BUTTON_BG;
- bgRolloverImage = ImageLoader.SOUND_SETTING_BUTTON_BG;
- pressedImage = ImageLoader.SOUND_SETTING_BUTTON_PRESSED;
+ bgImageID = ImageLoader.SOUND_SETTING_BUTTON_BG;
+ bgRolloverImageID = ImageLoader.SOUND_SETTING_BUTTON_BG;
+ pressedImageID = ImageLoader.SOUND_SETTING_BUTTON_PRESSED;
- }
}
if (toolTipTextKey != null)
@@ -171,13 +161,6 @@ public abstract class AbstractCallToggleButton
// All items are now instantiated and could safely load the skin.
loadSkin();
-
- int width = getBgImage().getWidth(null);
- int height = getBgImage().getHeight(null);
-
- this.setPreferredSize(new Dimension(width, height));
- this.setMaximumSize(new Dimension(width, height));
- this.setMinimumSize(new Dimension(width, height));
}
/**
@@ -256,15 +239,30 @@ public abstract class AbstractCallToggleButton
*/
public void loadSkin()
{
- setBgImage(ImageLoader.getImage(bgImage));
- setBgRolloverImage(ImageLoader.getImage(bgRolloverImage));
- setPressedImage(ImageLoader.getImage(pressedImage));
+ int width = CallToolBarButton.DEFAULT_WIDTH;
+ int height = CallToolBarButton.DEFAULT_HEIGHT;
+
+ if (bgImageID != null)
+ {
+ Image bgImage = ImageLoader.getImage(bgImageID);
+ setBgImage(bgImage);
+
+ width = bgImage.getWidth(this);
+ height = bgImage.getHeight(this);
+ }
+
+ setPreferredSize(new Dimension(width, height));
+ setMaximumSize(new Dimension(width, height));
+ setMinimumSize(new Dimension(width, height));
+
+ setBgRolloverImage(ImageLoader.getImage(bgRolloverImageID));
+ setPressedImage(ImageLoader.getImage(pressedImageID));
if (iconImageID != null)
{
if (!fullScreen && !settingsPanel)
setIconImage(ImageUtils.scaleImageWithinBounds(
- ImageLoader.getImage(iconImageID), 12, 12));
+ ImageLoader.getImage(iconImageID), 18, 18));
else
setIconImage(ImageLoader.getImage(iconImageID));
}
@@ -273,7 +271,7 @@ public abstract class AbstractCallToggleButton
{
if (!fullScreen && !settingsPanel)
setPressedIconImage(ImageUtils.scaleImageWithinBounds(
- ImageLoader.getImage(pressedIconImageID), 12, 12));
+ ImageLoader.getImage(pressedIconImageID), 18, 18));
else
setPressedIconImage(ImageLoader.getImage(pressedIconImageID));
}
@@ -290,7 +288,7 @@ public abstract class AbstractCallToggleButton
if (!fullScreen && !settingsPanel)
setIconImage(ImageUtils.scaleImageWithinBounds(
- ImageLoader.getImage(iconImageID), 12, 12));
+ ImageLoader.getImage(iconImageID), 18, 18));
else
setIconImage(ImageLoader.getImage(iconImageID));
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallHistoryButton.java b/src/net/java/sip/communicator/impl/gui/main/call/CallHistoryButton.java
index 476ad52..d00d60d 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/CallHistoryButton.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/CallHistoryButton.java
@@ -42,6 +42,11 @@ public class CallHistoryButton
private Image pressedImage;
/**
+ * The notification image.
+ */
+ private Image notificationImage;
+
+ /**
* Indicates if the history is visible.
*/
private boolean isHistoryVisible = false;
@@ -142,7 +147,10 @@ public class CallHistoryButton
*/
private void setHistoryView()
{
- isNotificationsView = false;
+ if (isNotificationsView)
+ isNotificationsView = false;
+ else
+ setIcon(null);
if (isHistoryVisible)
{
@@ -167,7 +175,6 @@ public class CallHistoryButton
{
int notificationCount = 0;
isNotificationsView = true;
- this.setBgImage(null);
Iterator<UINotificationGroup> groupsIter
= notificationGroups.iterator();
@@ -204,7 +211,29 @@ public class CallHistoryButton
this.setToolTipText(tooltipText + "</html>");
this.setBackground(new Color(200, 0, 0));
- this.setText(new Integer(notificationCount).toString());
+ this.setVerticalTextPosition(SwingConstants.TOP);
+
+ Image iconImage = ImageLoader.getImage(notificationImage,
+ new Integer(notificationCount).toString(), this);
+
+ if (isHistoryVisible)
+ {
+ setBgImage(ImageLoader.getImage(
+ pressedImage,
+ iconImage,
+ pressedImage.getWidth(null)/2
+ - notificationImage.getWidth(null)/2,
+ 0));
+ }
+ else
+ {
+ setBgImage(ImageLoader.getImage(
+ historyImage,
+ iconImage,
+ pressedImage.getWidth(null)/2
+ - notificationImage.getWidth(null)/2,
+ 0));
+ }
}
/**
@@ -218,6 +247,10 @@ public class CallHistoryButton
pressedImage
= ImageLoader.getImage(ImageLoader.CALL_HISTORY_BUTTON_PRESSED);
+ notificationImage
+ = ImageLoader.getImage(
+ ImageLoader.CALL_HISTORY_BUTTON_NOTIFICATION);
+
this.setPreferredSize(new Dimension(historyImage.getWidth(this),
historyImage.getHeight(this)));
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/CallPanel.java
index 966a7a2..e8a5c2a 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/CallPanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/CallPanel.java
@@ -14,7 +14,6 @@ import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
-import javax.swing.border.*;
import javax.swing.event.*;
import net.java.sip.communicator.impl.gui.*;
@@ -29,7 +28,6 @@ import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.Logger;
import net.java.sip.communicator.util.skin.*;
import net.java.sip.communicator.util.swing.*;
-import net.java.sip.communicator.util.swing.border.*;
import org.jitsi.service.neomedia.*;
import org.jitsi.service.neomedia.device.*;
@@ -108,11 +106,6 @@ public class CallPanel
/**
* The hang up button name.
*/
- private static final String HANGUP_BUTTON = "HANGUP_BUTTON";
-
- /**
- * The hang up button name.
- */
private static final String MERGE_BUTTON = "MERGE_BUTTON";
/**
@@ -128,7 +121,7 @@ public class CallPanel
/**
* The panel containing call settings.
*/
- private final TransparentPanel settingsPanel = new OrderedTransparentPanel();
+ private JComponent settingsPanel;
/**
* The panel representing the call. For conference calls this would be an
@@ -181,17 +174,20 @@ public class CallPanel
/**
* The dial button, which opens a keypad dialog.
*/
- private SIPCommButton dialButton = new SIPCommButton(
- ImageLoader.getImage(ImageLoader.CALL_SETTING_BUTTON_BG),
- ImageLoader.getImage(ImageLoader.DIAL_BUTTON));
+ private CallToolBarButton dialButton = new CallToolBarButton(
+ ImageLoader.getImage(ImageLoader.DIAL_BUTTON),
+ DIAL_BUTTON,
+ GuiActivator.getResources().getI18NString("service.gui.DIALPAD"));
/**
* The conference button.
*/
- private SIPCommButton conferenceButton
- = new SIPCommButton(
- ImageLoader.getImage(ImageLoader.CALL_SETTING_BUTTON_BG),
- ImageLoader.getImage(ImageLoader.ADD_TO_CALL_BUTTON));
+ private CallToolBarButton conferenceButton
+ = new CallToolBarButton(
+ ImageLoader.getImage(ImageLoader.ADD_TO_CALL_BUTTON),
+ CONFERENCE_BUTTON,
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CREATE_CONFERENCE_CALL"));
/**
* Chat button.
@@ -216,10 +212,12 @@ public class CallPanel
/**
* Merge button.
*/
- private SIPCommButton mergeButton =
- new SIPCommButton(
- ImageLoader.getImage(ImageLoader.CALL_SETTING_BUTTON_BG),
- ImageLoader.getImage(ImageLoader.MERGE_CALL_BUTTON));
+ private CallToolBarButton mergeButton =
+ new CallToolBarButton(
+ ImageLoader.getImage(ImageLoader.MERGE_CALL_BUTTON),
+ MERGE_BUTTON,
+ GuiActivator.getResources().getI18NString(
+ "service.gui.MERGE_TO_CALL"));
/**
* The call represented in this dialog.
@@ -264,7 +262,7 @@ public class CallPanel
/**
* Sound remote level label.
*/
- private OutputVolumeControlButton remoteLevel;
+ private Component remoteLevel;
/**
* A collection of listeners, registered for call title change events.
@@ -290,23 +288,28 @@ public class CallPanel
this.call = call;
this.callWindow = callWindow;
+ settingsPanel
+ = CallPeerRendererUtils.createButtonBar(false, null);
+
holdButton = new HoldButton(call);
recordButton = new RecordButton(call);
videoButton = new LocalVideoButton(call);
showHideVideoButton = new ShowHideVideoButton(call);
desktopSharingButton = new DesktopSharingButton(call);
transferCallButton = new TransferCallButton(call);
- fullScreenButton = new FullScreenButton(this);
- chatButton = new SIPCommButton(
- ImageLoader.getImage(ImageLoader.CALL_SETTING_BUTTON_BG),
- ImageLoader.getImage(ImageLoader.CHAT_BUTTON_SMALL_WHITE));
+ fullScreenButton = new FullScreenButton(this, false);
+ chatButton = new CallToolBarButton(
+ ImageLoader.getImage(ImageLoader.CHAT_BUTTON_SMALL_WHITE),
+ CHAT_BUTTON,
+ GuiActivator.getResources().getI18NString("service.gui.CHAT"));
+
localLevel = new InputVolumeControlButton(
call,
ImageLoader.MICROPHONE,
ImageLoader.MUTE_BUTTON,
false, true, false);
remoteLevel = new OutputVolumeControlButton(
- ImageLoader.VOLUME_CONTROL_BUTTON, false, true);
+ ImageLoader.VOLUME_CONTROL_BUTTON, false, true).getComponent();
this.callDurationTimer = new Timer(1000, new CallTimerListener());
this.callDurationTimer.setRepeats(true);
@@ -345,7 +348,7 @@ public class CallPanel
callPeers.next().addCallPeerConferenceListener(this);
// Initializes all buttons and common panels.
- init();
+ initToolBar();
initPluginComponents();
}
@@ -353,15 +356,12 @@ public class CallPanel
/**
* Initializes all buttons and common panels
*/
- private void init()
+ private void initToolBar()
{
- hangupButton = new SIPCommButton(
- ImageLoader.getImage(ImageLoader.HANGUP_BUTTON_BG));
+ hangupButton = new HangupButton(this);
- holdButton.setIndex(2);
- recordButton.setIndex(3);
- videoButton.setIndex(11);
- showHideVideoButton.setIndex(12);
+ // Initializes the order of buttons in the call tool bar.
+ initButtonIndexes();
showHideVideoButton.setPeerRenderer(((CallRenderer) callPanel)
.getCallPeerRenderer(call.getCallPeers().next()));
@@ -388,42 +388,9 @@ public class CallPanel
}
});
- desktopSharingButton.setIndex(8);
- transferCallButton.setIndex(5);
- fullScreenButton.setIndex(10);
-
- chatButton.setName(CHAT_BUTTON);
- chatButton.setToolTipText(
- GuiActivator.getResources().getI18NString("service.gui.CHAT"));
chatButton.addActionListener(this);
- chatButton.setIndex(19);
-
- localLevel.setIndex(6);
- remoteLevel.setIndex(7);
-
- dialButton.setIndex(0);
- dialButton.setName(DIAL_BUTTON);
- dialButton.setToolTipText(
- GuiActivator.getResources().getI18NString("service.gui.DIALPAD"));
dialButton.addActionListener(this);
-
- conferenceButton.setIndex(1);
- conferenceButton.setName(CONFERENCE_BUTTON);
- conferenceButton.setToolTipText(
- GuiActivator.getResources().getI18NString(
- "service.gui.CREATE_CONFERENCE_CALL"));
conferenceButton.addActionListener(this);
-
- hangupButton.setName(HANGUP_BUTTON);
- hangupButton.setToolTipText(
- GuiActivator.getResources().getI18NString("service.gui.HANG_UP"));
- hangupButton.addActionListener(this);
-
- mergeButton.setIndex(4);
- mergeButton.setName(MERGE_BUTTON);
- mergeButton.setToolTipText(
- GuiActivator.getResources().getI18NString(
- "service.gui.MERGE_TO_CALL"));
mergeButton.addActionListener(this);
/*
@@ -474,24 +441,50 @@ public class CallPanel
if(GuiActivator.getConfigurationService()
.getBoolean(SHOW_CALL_INFO_BUTON_PROP, true))
{
- infoButton = new SIPCommButton(
- ImageLoader.getImage(ImageLoader.CALL_SETTING_BUTTON_BG),
- ImageLoader.getImage(ImageLoader.CALL_INFO));
- infoButton.setName(INFO_BUTTON);
- infoButton.setToolTipText(
- GuiActivator.getResources().getI18NString(
- "service.gui.PRESS_FOR_CALL_INFO"));
+ infoButton = new CallToolBarButton(
+ ImageLoader.getImage(ImageLoader.CALL_INFO),
+ INFO_BUTTON,
+ GuiActivator.getResources().getI18NString(
+ "service.gui.PRESS_FOR_CALL_INFO"));
+
infoButton.addActionListener(this);
- infoButton.setIndex(20);
settingsPanel.add(infoButton);
}
- dtmfHandler = new DTMFHandler(this);
+ settingsPanel.add(hangupButton);
- JComponent bottomBar = createBottomBar();
+ dtmfHandler = new DTMFHandler(this);
add(callPanel, BorderLayout.CENTER);
- add(bottomBar, BorderLayout.SOUTH);
+ add(createBottomBar(), BorderLayout.SOUTH);
+ }
+
+ /**
+ * Initializes buttons order in the call tool bar.
+ */
+ private void initButtonIndexes()
+ {
+ dialButton.setIndex(0);
+ conferenceButton.setIndex(1);
+ holdButton.setIndex(2);
+ recordButton.setIndex(3);
+ mergeButton.setIndex(4);
+ transferCallButton.setIndex(5);
+ localLevel.setIndex(6);
+
+ if (remoteLevel instanceof OrderedComponent)
+ ((OrderedComponent) remoteLevel).setIndex(7);
+
+ desktopSharingButton.setIndex(8);
+ fullScreenButton.setIndex(10);
+ videoButton.setIndex(11);
+ showHideVideoButton.setIndex(12);
+ chatButton.setIndex(19);
+
+ if (infoButton != null)
+ infoButton.setIndex(20);
+
+ hangupButton.setIndex(100);
}
/**
@@ -503,11 +496,7 @@ public class CallPanel
JButton button = (JButton) evt.getSource();
String buttonName = button.getName();
- if (buttonName.equals(HANGUP_BUTTON))
- {
- actionPerformedOnHangupButton(false);
- }
- else if (buttonName.equals(MERGE_BUTTON))
+ if (buttonName.equals(MERGE_BUTTON))
{
Collection<Call> calls = CallManager.getActiveCalls();
@@ -1612,10 +1601,10 @@ public class CallPanel
*/
private JComponent createBottomBar()
{
- JComponent bottomBar = new TransparentPanel();
+ JComponent bottomBar
+ = new TransparentPanel(new FlowLayout(FlowLayout.CENTER, 0, 0));
- bottomBar.setBorder(
- new ExtendedEtchedBorder(EtchedBorder.LOWERED, 1, 0, 0, 0));
+ bottomBar.setBorder(BorderFactory.createEmptyBorder(0, 30, 2, 30));
if (OSUtils.IS_MAC)
{
@@ -1625,9 +1614,7 @@ public class CallPanel
.getColor("service.gui.MAC_PANEL_BACKGROUND")));
}
- bottomBar.setLayout(new BorderLayout());
- bottomBar.add(settingsPanel, BorderLayout.WEST);
- bottomBar.add(hangupButton, BorderLayout.EAST);
+ bottomBar.add(settingsPanel);
return bottomBar;
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallPeerRendererUtils.java b/src/net/java/sip/communicator/impl/gui/main/call/CallPeerRendererUtils.java
index f6a4656..543af5d 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/CallPeerRendererUtils.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/CallPeerRendererUtils.java
@@ -13,7 +13,6 @@ import javax.swing.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.utils.*;
-import net.java.sip.communicator.util.skin.*;
import net.java.sip.communicator.util.swing.*;
/**
@@ -27,30 +26,6 @@ import net.java.sip.communicator.util.swing.*;
public class CallPeerRendererUtils
{
/**
- * Creates a new <tt>Component</tt> through which the user would be able to
- * exit the full screen mode.
- *
- * @param renderer the renderer through which we exit the full screen mode
- * @return the newly created component
- */
- public static Component createExitFullScreenButton(
- final CallRenderer renderer)
- {
- JButton button = new ExitFullScreenButton();
-
- button.setToolTipText(GuiActivator.getResources().getI18NString(
- "service.gui.EXIT_FULL_SCREEN_TOOL_TIP"));
- button.addActionListener(new ActionListener()
- {
- public void actionPerformed(ActionEvent event)
- {
- renderer.exitFullScreen();
- }
- });
- return button;
- }
-
- /**
* Sets the given <tt>background</tt> color to the given <tt>component</tt>.
*
* @param component the component to which we set the background
@@ -87,24 +62,27 @@ public class CallPeerRendererUtils
/**
* Creates a buttons bar from the given list of button components.
*
- * @param heavyweight indicates if the created button bar should be heavy
- * weight component (useful in full screen mode)
+ * @param fullScreen indicates if the created button bar would be shown in
+ * full screen mode
* @param buttons the list of buttons to add in the created button bar
* @return the created button bar
*/
- public static Component createButtonBar(boolean heavyweight,
+ public static JComponent createButtonBar(boolean fullScreen,
Component[] buttons)
{
- Container buttonBar
- = heavyweight ? new Container() : new TransparentPanel();
+ JComponent buttonBar = fullScreen
+ ? new CallToolBarPanel(true)
+ : new CallToolBarPanel(false);
- buttonBar.setLayout(new FlowLayout(FlowLayout.CENTER, 3, 3));
-
- for (Component button : buttons)
+ if (buttons != null)
{
- if (button != null)
- buttonBar.add(button);
+ for (Component button : buttons)
+ {
+ if (button != null)
+ ((Container) buttonBar).add(button);
+ }
}
+
return buttonBar;
}
@@ -137,32 +115,74 @@ public class CallPeerRendererUtils
}
/**
- * Full screen exit button. Implements <tt>Skinnable</tt>.
+ * The tool bar container shown in the call window.
*/
- public static class ExitFullScreenButton
- extends SIPCommButton
- implements Skinnable
+ private static class CallToolBarPanel
+ extends OrderedTransparentPanel
{
- /**
- * Creates an instance of SIPCommButton.
- */
- public ExitFullScreenButton()
+ final Color settingsColor
+ = new Color(GuiActivator.getResources().getColor(
+ "service.gui.CALL_TOOL_BAR"));
+
+ final Color settingsFullScreenColor
+ = new Color(GuiActivator.getResources().getColor(
+ "service.gui.CALL_TOOL_BAR_FULL_SCREEN"));
+
+ final Image buttonSeparatorImage
+ = ImageLoader.getImage(ImageLoader.CALL_TOOLBAR_SEPARATOR);
+
+ private final boolean isFullScreen;
+
+ private final int TOOL_BAR_BORDER = 2;
+
+ private final int TOOL_BAR_X_GAP = 3;
+
+ public CallToolBarPanel(boolean isFullScreen)
{
- super(
- ImageLoader.getImage(ImageLoader.FULL_SCREEN_BUTTON_BG),
- ImageLoader.getImage(ImageLoader.EXIT_FULL_SCREEN_BUTTON));
+ this.isFullScreen = isFullScreen;
+
+ setLayout(new FlowLayout(FlowLayout.CENTER, 3, 0));
+ setBorder(BorderFactory.createEmptyBorder(
+ TOOL_BAR_BORDER,
+ TOOL_BAR_BORDER,
+ TOOL_BAR_BORDER,
+ TOOL_BAR_BORDER));
}
- /**
- * Reloads icons.
- */
- public void loadSkin()
+ public void paintComponent(Graphics g)
{
- setBackgroundImage(
- ImageLoader.getImage(ImageLoader.FULL_SCREEN_BUTTON_BG));
- setIconImage(
- ImageLoader.getImage(ImageLoader.EXIT_FULL_SCREEN_BUTTON));
- }
+ super.paintComponent(g);
+
+ g = g.create();
+
+ AntialiasingManager.activateAntialiasing(g);
+
+ try
+ {
+ if (isFullScreen)
+ g.setColor(settingsFullScreenColor);
+ else
+ g.setColor(settingsColor);
+
+ g.fillRoundRect(0, 0, getWidth(), getHeight(), 8, 8);
+
+ // We add the border.
+ int x = CallToolBarButton.DEFAULT_WIDTH
+ + TOOL_BAR_BORDER + TOOL_BAR_X_GAP;
+
+ while (x < getWidth() - TOOL_BAR_BORDER - TOOL_BAR_X_GAP)
+ {
+ g.drawImage(buttonSeparatorImage, x + 1,
+ (getHeight() - buttonSeparatorImage.getHeight(this))/2,
+ this);
+ x += CallToolBarButton.DEFAULT_WIDTH + TOOL_BAR_X_GAP;
+ }
+ }
+ finally
+ {
+ g.dispose();
+ }
+ }
}
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/CallToolBarButton.java b/src/net/java/sip/communicator/impl/gui/main/call/CallToolBarButton.java
new file mode 100644
index 0000000..c63e631
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/call/CallToolBarButton.java
@@ -0,0 +1,72 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.gui.main.call;
+
+import java.awt.*;
+
+import net.java.sip.communicator.util.swing.*;
+
+/**
+ * The <tt>CallBarButton</tt> is a button shown in the call window tool bar.
+ *
+ * @author Yana Stamcheva
+ */
+public class CallToolBarButton
+ extends SIPCommButton
+{
+ /**
+ * The default width of a button in the call tool bar.
+ */
+ public static final int DEFAULT_WIDTH = 44;
+
+ /**
+ * The default height of a button in the call tool bar.
+ */
+ public static final int DEFAULT_HEIGHT = 38;
+
+ /**
+ * Creates an instance of <tt>CallToolBarButton</tt>.
+ */
+ public CallToolBarButton()
+ {
+ this(null, null);
+ }
+
+ /**
+ * Creates an instance of <tt>CallToolBarButton</tt> by specifying the icon
+ * image and the tool tip text.
+ *
+ * @param iconImage the icon of this button
+ * @param tooltipText the text to show in the button tooltip
+ */
+ public CallToolBarButton( Image iconImage,
+ String tooltipText)
+ {
+ this(iconImage, null, tooltipText);
+ }
+
+ /**
+ * Creates an instance of <tt>CallToolBarButton</tt> by specifying the icon
+ * image, the name of the button and the tool tip text.
+ *
+ * @param iconImage the icon of this button
+ * @param buttonName the name of this button
+ * @param tooltipText the text to show in the button tooltip
+ */
+ public CallToolBarButton( Image iconImage,
+ String buttonName,
+ String tooltipText)
+ {
+ super(null, iconImage);
+
+ setIconImage(iconImage);
+
+ setPreferredSize(new Dimension(DEFAULT_WIDTH, DEFAULT_HEIGHT));
+ setName(buttonName);
+ setToolTipText(tooltipText);
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/FullScreenButton.java b/src/net/java/sip/communicator/impl/gui/main/call/FullScreenButton.java
index 216bde8..714b0fc 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/FullScreenButton.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/FullScreenButton.java
@@ -6,6 +6,7 @@
*/
package net.java.sip.communicator.impl.gui.main.call;
+import java.awt.*;
import java.awt.event.*;
import net.java.sip.communicator.impl.gui.*;
@@ -24,19 +25,30 @@ public class FullScreenButton
implements Skinnable
{
/**
+ * Indicates if this buttons is shown in full screen view or normal window.
+ */
+ private boolean isFullScreen = false;
+
+ /**
* Initializes a new <tt>FullScreenButton</tt> instance which is to
* enter the full screen mode.
*
* @param callContainer the parent <tt>CallContainer</tt>, where this button
* is contained
*/
- public FullScreenButton(final CallPanel callContainer)
+ public FullScreenButton(final CallPanel callContainer,
+ final boolean isFullScreen)
{
- super( ImageLoader.getImage(ImageLoader.CALL_SETTING_BUTTON_BG),
- ImageLoader.getImage(ImageLoader.ENTER_FULL_SCREEN_BUTTON));
+ this.isFullScreen = isFullScreen;
+
+ if (isFullScreen)
+ setToolTipText(GuiActivator.getResources().getI18NString(
+ "service.gui.EXIT_FULL_SCREEN_TOOL_TIP"));
+ else
+ setToolTipText(GuiActivator.getResources().getI18NString(
+ "service.gui.ENTER_FULL_SCREEN_TOOL_TIP"));
- setToolTipText(GuiActivator.getResources().getI18NString(
- "service.gui.ENTER_FULL_SCREEN_TOOL_TIP"));
+ loadSkin();
addActionListener(new ActionListener()
{
@@ -49,7 +61,10 @@ public class FullScreenButton
*/
public void actionPerformed(ActionEvent evt)
{
- callContainer.getCurrentCallRenderer().enterFullScreen();
+ if (isFullScreen)
+ callContainer.getCurrentCallRenderer().exitFullScreen();
+ else
+ callContainer.getCurrentCallRenderer().enterFullScreen();
}
});
}
@@ -59,10 +74,13 @@ public class FullScreenButton
*/
public void loadSkin()
{
- setBackgroundImage(ImageLoader.getImage(
- ImageLoader.CALL_SETTING_BUTTON_BG));
+ setPreferredSize(new Dimension(44, 38));
- setIconImage(ImageLoader.getImage(
+ if (isFullScreen)
+ setIconImage(ImageLoader.getImage(
+ ImageLoader.EXIT_FULL_SCREEN_BUTTON));
+ else
+ setIconImage(ImageLoader.getImage(
ImageLoader.ENTER_FULL_SCREEN_BUTTON));
}
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/FullScreenLayout.java b/src/net/java/sip/communicator/impl/gui/main/call/FullScreenLayout.java
index 34032b3..6d1e861 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/FullScreenLayout.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/FullScreenLayout.java
@@ -34,17 +34,30 @@ public class FullScreenLayout
private Component south;
/**
+ * The vertical gap between the center and the south components.
+ */
+ private int yGap = 0;
+
+ /**
* Initializes a new <tt>FullScreenLayout</tt> instance.
*
* @param overlay <tt>true</tt> to lay out the <tt>Component</tt> at
* {@link #SOUTH} on top of the <tt>Component</tt> at {@link #CENTER} i.e as
* an overlay; otherwise, <tt>false</tt>
+ * @oaram yGap the gap betwen the center and the south component
*/
- public FullScreenLayout(boolean overlay)
+ public FullScreenLayout(boolean overlay, int yGap)
{
this.overlay = overlay;
+ this.yGap = yGap;
}
+ /**
+ * Adds the given component to this layout.
+ *
+ * @param name the name of the constraint (CENTER or SOUTH)
+ * @param comp the component to add to this layout
+ */
public void addLayoutComponent(String name, Component comp)
{
if (CENTER.equals(name))
@@ -72,6 +85,11 @@ public class FullScreenLayout
return layoutComponents;
}
+ /**
+ * Lays out the components added in the given parent container
+ *
+ * @param parent the parent container to lay out
+ */
public void layoutContainer(Container parent)
{
int southWidth;
@@ -97,7 +115,7 @@ public class FullScreenLayout
* If the Component at the SOUTH is not to be shown as an overlay,
* make room for it bellow the Component at the CENTER.
*/
- int yOffset = overlay ? 0 : southHeight;
+ int yOffset = overlay ? 0 : southHeight + yGap;
center.setBounds(
0,
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/HangupButton.java b/src/net/java/sip/communicator/impl/gui/main/call/HangupButton.java
new file mode 100644
index 0000000..645df75
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/call/HangupButton.java
@@ -0,0 +1,42 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.gui.main.call;
+
+import java.awt.event.*;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.impl.gui.utils.*;
+
+/**
+ * The hangup button shown in the call window.
+ *
+ * @author Yana Stamcheva
+ */
+public class HangupButton
+ extends CallToolBarButton
+{
+ /**
+ * Creates an instance of <tt>HangupButton</tt>, by specifying the parent
+ * call panel.
+ *
+ * @param callPanel the parent call panel
+ */
+ public HangupButton(final CallPanel callPanel)
+ {
+ super( ImageLoader.getImage(ImageLoader.HANGUP_BUTTON_BG),
+ GuiActivator.getResources()
+ .getI18NString("service.gui.HANG_UP"));
+
+ addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ callPanel.actionPerformedOnHangupButton(false);
+ }
+ });
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/InputVolumeControlButton.java b/src/net/java/sip/communicator/impl/gui/main/call/InputVolumeControlButton.java
index f318667..d161548 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/InputVolumeControlButton.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/InputVolumeControlButton.java
@@ -51,8 +51,14 @@ public class InputVolumeControlButton
*/
private final VolumeControl volumeControl;
- private final VolumeControlSlider sliderMenu;
+ /**
+ * The slider popup menu.
+ */
+ private final JPopupMenu sliderMenu;
+ /**
+ * Indicates if this component is shown in full screen mode.
+ */
private final boolean fullScreen;
/**
@@ -135,7 +141,9 @@ public class InputVolumeControlButton
volumeControl = getVolumeControl();
// Creates the menu that would contain the volume control component.
- sliderMenu = new VolumeControlSlider(volumeControl);
+ sliderMenu
+ = new VolumeControlSlider(volumeControl, JSlider.VERTICAL)
+ .getPopupMenu();
sliderMenu.setInvoker(this);
addMouseListener(new MouseAdapter()
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPanel.java
index 476d089..f3558bb 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPanel.java
@@ -209,7 +209,7 @@ public class OneToOneCallPanel
// Lay out the main Components of the UI.
final Container contentPane = frame.getContentPane();
- contentPane.setLayout(new FullScreenLayout(false));
+ contentPane.setLayout(new FullScreenLayout(false, 10));
if (buttonBar != null)
contentPane.add(buttonBar, FullScreenLayout.SOUTH);
if (center != null)
@@ -331,7 +331,7 @@ public class OneToOneCallPanel
*
* @return the buttons bar <tt>Component</tt>
*/
- private Component createFullScreenButtonBar()
+ private JComponent createFullScreenButtonBar()
{
ShowHideVideoButton showHideButton = new ShowHideVideoButton(
call, true, callContainer.isShowHideVideoButtonSelected());
@@ -341,16 +341,17 @@ public class OneToOneCallPanel
Component[] buttons
= new Component[]
{
+ new OutputVolumeControlButton(true).getComponent(),
new InputVolumeControlButton(call, true, callPeer.isMute()),
- new OutputVolumeControlButton(true),
new HoldButton(call,
true,
CallPeerState.isOnHold(callPeer.getState())),
new RecordButton(call, true, callContainer.isRecordingStarted()),
+ new FullScreenButton(callContainer, true),
new LocalVideoButton(
call, true, callContainer.isVideoButtonSelected()),
showHideButton,
- CallPeerRendererUtils.createExitFullScreenButton(this)
+ new HangupButton(callContainer)
};
return CallPeerRendererUtils.createButtonBar(true, buttons);
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPeerPanel.java b/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPeerPanel.java
index 7242a22..f60cafd 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPeerPanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/OneToOneCallPeerPanel.java
@@ -142,7 +142,7 @@ public class OneToOneCallPeerPanel
/**
* Sound remote level label.
*/
- private OutputVolumeControlButton remoteLevel;
+ private Component remoteLevel;
/**
* The center component.
@@ -356,7 +356,7 @@ public class OneToOneCallPeerPanel
ImageLoader.MUTE_BUTTON,
false, false, false);
remoteLevel = new OutputVolumeControlButton(
- ImageLoader.HEADPHONE, false, false);
+ ImageLoader.HEADPHONE, false, false).getComponent();
final SoundLevelIndicator localLevelIndicator
= new SoundLevelIndicator(
@@ -831,9 +831,8 @@ public class OneToOneCallPeerPanel
localLevel.setIcon(new ImageIcon(
ImageLoader.getImage(ImageLoader.MICROPHONE)));
- if(remoteLevel != null)
- remoteLevel.setIcon(new ImageIcon(
- ImageLoader.getImage(ImageLoader.HEADPHONE)));
+ if(remoteLevel != null && remoteLevel instanceof Skinnable)
+ ((Skinnable) remoteLevel).loadSkin();
if(muteStatusLabel.getIcon() != null)
muteStatusLabel.setIcon(new ImageIcon(
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/OutputVolumeControlButton.java b/src/net/java/sip/communicator/impl/gui/main/call/OutputVolumeControlButton.java
index 78a157d..13b6771 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/OutputVolumeControlButton.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/OutputVolumeControlButton.java
@@ -14,6 +14,7 @@ import javax.swing.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.resources.*;
+import net.java.sip.communicator.util.*;
import net.java.sip.communicator.util.swing.*;
import org.jitsi.service.neomedia.*;
@@ -26,7 +27,6 @@ import org.jitsi.service.neomedia.*;
* @author Damian Minkov
*/
public class OutputVolumeControlButton
- extends SIPCommButton
{
/**
* The background image.
@@ -44,6 +44,16 @@ public class OutputVolumeControlButton
private ImageID iconImageID;
/**
+ * Indicates if we're in full screen mode.
+ */
+ private final boolean fullScreen;
+
+ /**
+ *
+ */
+ private final boolean inButtonToolBar;
+
+ /**
* Creates not full screen button.
*/
public OutputVolumeControlButton()
@@ -53,68 +63,122 @@ public class OutputVolumeControlButton
/**
* Creates volume control button.
+ *
* @param fullScreen is full screen.
*/
public OutputVolumeControlButton(boolean fullScreen)
{
- this(ImageLoader.VOLUME_CONTROL_BUTTON, fullScreen, false);
+ this(ImageLoader.VOLUME_CONTROL_BUTTON, fullScreen, true);
}
/**
* Creates volume control button.
+ *
* @param iconImageID the image.
* @param fullScreen is full screen.
+ * @param inButtonToolBar indicates if this button is shown in the button
+ * tool bar
*/
public OutputVolumeControlButton(ImageID iconImageID,
boolean fullScreen,
- boolean inSettingsPanel)
+ boolean inButtonToolBar)
{
- super( ImageLoader.getImage(ImageLoader.SOUND_SETTING_BUTTON_PRESSED),
- ImageLoader.getImage(iconImageID));
+ this.fullScreen = fullScreen;
+ this.inButtonToolBar = inButtonToolBar;
- initVolumeControlButton(fullScreen, inSettingsPanel, iconImageID,
- "service.gui.VOLUME_CONTROL_TOOL_TIP");
+ this.iconImageID = iconImageID;
}
/**
- *
- * @param fullScreen
- * @param inSettingsPanel
- * @param iconImageID
- * @param toolTipTextKey
+ * Returns the component associated with this output volume control button.
+ *
+ * @return the component associated with this output volume control button
*/
- public void initVolumeControlButton(final boolean fullScreen,
- boolean inSettingsPanel,
- ImageID iconImageID,
- String toolTipTextKey)
+ public Component getComponent()
{
- this.iconImageID = iconImageID;
-
- if (fullScreen)
- {
- bgImage = ImageLoader.FULL_SCREEN_BUTTON_BG;
- pressedImage = ImageLoader.FULL_SCREEN_BUTTON_BG_PRESSED;
- }
+ if (!fullScreen)
+ return createVolumeControlButton(
+ inButtonToolBar,
+ iconImageID,
+ "service.gui.VOLUME_CONTROL_TOOL_TIP");
else
+ return createSliderComponent();
+ }
+
+ /**
+ * Creates the slider component for the full screen interface.
+ *
+ * @return the created component
+ */
+ public Component createSliderComponent()
+ {
+ final Color bgColor
+ = new Color(GuiActivator.getResources().getColor(
+ "service.gui.CALL_TOOL_BAR_SOUND_BG"));
+
+ @SuppressWarnings("serial")
+ TransparentPanel soundPanel = new TransparentPanel(
+ new FlowLayout(FlowLayout.LEFT, 0, 0))
{
- if(inSettingsPanel)
+ public void paintComponent(Graphics g)
{
- bgImage = ImageLoader.CALL_SETTING_BUTTON_BG;
- pressedImage = ImageLoader.CALL_SETTING_BUTTON_PRESSED_BG;
- }
- else
- {
- bgImage = ImageLoader.SOUND_SETTING_BUTTON_BG;
- pressedImage = ImageLoader.SOUND_SETTING_BUTTON_PRESSED;
+ super.paintComponent(g);
+
+ g = g.create();
+
+ AntialiasingManager.activateAntialiasing(g);
+
+ try
+ {
+ g.setColor(bgColor);
+
+ g.fillRoundRect(0, 0, getWidth()-1, getHeight()-1, 8, 8);
+ }
+ finally
+ {
+ g.dispose();
+ }
}
- }
+ };
+
+ soundPanel.setBorder(BorderFactory.createEmptyBorder(3, 3, 3, 3));
+ final VolumeControl volumeControl
+ = GuiActivator.getMediaService().getOutputVolumeControl();
+
+ // Creates the menu that would contain the volume control component.
+ VolumeControlSlider slider
+ = new VolumeControlSlider(volumeControl, JSlider.HORIZONTAL);
+
+ soundPanel.add(new JLabel(GuiActivator.getResources()
+ .getImage("service.gui.icons.NO_SOUND_ICON")));
+ soundPanel.add(slider);
+ soundPanel.add(new JLabel(GuiActivator.getResources()
+ .getImage("service.gui.icons.SOUND_MENU_ICON")));
+
+ return soundPanel;
+ }
+
+ /**
+ * Initializes the volume control button.
+ *
+ * @param fullScreen indicates if we're in fullscreen mode
+ * @param isButtonBar indicates if this button is shown in the button
+ * toolbar
+ * @param iconImageID the identifier of the button icon
+ * @param toolTipTextKey the key of the tool tip text
+ */
+ public Component createVolumeControlButton( boolean isButtonBar,
+ ImageID iconImageID,
+ String toolTipTextKey)
+ {
+ this.iconImageID = iconImageID;
- // Loads the skin of this button.
- loadSkin();
+ final SIPCommButton volumeControlButton
+ = new VolumeControlButton(isButtonBar);
if (toolTipTextKey != null)
{
- setToolTipText(
+ volumeControlButton.setToolTipText(
GuiActivator.getResources().getI18NString(toolTipTextKey));
}
@@ -122,40 +186,78 @@ public class OutputVolumeControlButton
= GuiActivator.getMediaService().getOutputVolumeControl();
// Creates the menu that would contain the volume control component.
- final VolumeControlSlider sliderMenu
- = new VolumeControlSlider(volumeControl);
+ final JPopupMenu sliderMenu
+ = new VolumeControlSlider(volumeControl, JSlider.VERTICAL)
+ .getPopupMenu();
- sliderMenu.setInvoker(this);
+ sliderMenu.setInvoker(volumeControlButton);
- this.addActionListener(new ActionListener()
+ volumeControlButton.addActionListener(new ActionListener()
{
public void actionPerformed(ActionEvent arg0)
{
- Point location = new Point(getX(), getY() + getHeight());
+ Point location = new Point(
+ volumeControlButton.getX(),
+ volumeControlButton.getY()
+ + volumeControlButton.getHeight());
- SwingUtilities.convertPointToScreen(location,
- OutputVolumeControlButton.this.getParent());
-
- if(fullScreen)
- location.setLocation(location.getX(),
- location.getY()
- - sliderMenu.getPreferredSize().getHeight()
- - getHeight());
+ SwingUtilities.convertPointToScreen(
+ location,
+ volumeControlButton.getParent());
sliderMenu.setLocation(location);
sliderMenu.setVisible(!sliderMenu.isVisible());
}
});
+
+ return volumeControlButton;
}
/**
- * Loads images.
+ * The <tt>VolumeControlButton</tt>
*/
- public void loadSkin()
+ @SuppressWarnings("serial")
+ private class VolumeControlButton
+ extends SIPCommButton
{
- setBackgroundImage(ImageLoader.getImage(bgImage));
- setPressedImage(ImageLoader.getImage(pressedImage));
- setIconImage(ImageLoader.getImage(iconImageID));
+ public VolumeControlButton(boolean inSettingsPanel)
+ {
+ super(
+ ImageLoader.getImage(ImageLoader.SOUND_SETTING_BUTTON_PRESSED),
+ ImageLoader.getImage(iconImageID));
+
+ if(inSettingsPanel)
+ {
+ bgImage = ImageLoader.CALL_SETTING_BUTTON_BG;
+ pressedImage = ImageLoader.CALL_SETTING_BUTTON_PRESSED_BG;
+ }
+ else
+ {
+ bgImage = ImageLoader.SOUND_SETTING_BUTTON_BG;
+ pressedImage = ImageLoader.SOUND_SETTING_BUTTON_PRESSED;
+ }
+
+ // Loads the skin of this button.
+ loadSkin();
+ }
+
+ /**
+ * Loads images.
+ */
+ public void loadSkin()
+ {
+ setBackgroundImage(ImageLoader.getImage(bgImage));
+ setPressedImage(ImageLoader.getImage(pressedImage));
+
+ if (iconImageID != null)
+ {
+ if (!fullScreen && !inButtonToolBar)
+ setIconImage(ImageUtils.scaleImageWithinBounds(
+ ImageLoader.getImage(iconImageID), 18, 18));
+ else
+ setIconImage(ImageLoader.getImage(iconImageID));
+ }
+ }
}
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/TransferCallButton.java b/src/net/java/sip/communicator/impl/gui/main/call/TransferCallButton.java
index 127a193..6f31bec 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/TransferCallButton.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/TransferCallButton.java
@@ -12,8 +12,6 @@ import java.util.*;
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.protocol.*;
-import net.java.sip.communicator.util.skin.*;
-import net.java.sip.communicator.util.swing.*;
/**
* Represents an UI means to transfer (the <tt>Call</tt> of) an associated
@@ -24,8 +22,7 @@ import net.java.sip.communicator.util.swing.*;
* @author Adam Netocny
*/
public class TransferCallButton
- extends SIPCommButton
- implements Skinnable
+ extends CallToolBarButton
{
/**
* The <tt>Call</tt> to be transfered.
@@ -42,14 +39,12 @@ public class TransferCallButton
*/
public TransferCallButton(Call c)
{
- super( ImageLoader.getImage(ImageLoader.CALL_SETTING_BUTTON_BG),
- ImageLoader.getImage(ImageLoader.TRANSFER_CALL_BUTTON));
+ super( ImageLoader.getImage(ImageLoader.TRANSFER_CALL_BUTTON),
+ GuiActivator.getResources().getI18NString(
+ "service.gui.TRANSFER_BUTTON_TOOL_TIP"));
this.call = c;
- setToolTipText(GuiActivator.getResources().getI18NString(
- "service.gui.TRANSFER_BUTTON_TOOL_TIP"));
-
OperationSetAdvancedTelephony<?> telephony =
call.getProtocolProvider()
.getOperationSet(OperationSetAdvancedTelephony.class);
@@ -131,16 +126,4 @@ public class TransferCallButton
}
return transferCalls;
}
-
- /**
- * Reloads icons.
- */
- public void loadSkin()
- {
- this.setBackgroundImage(ImageLoader.getImage(
- ImageLoader.CALL_SETTING_BUTTON_BG));
-
- this.setIconImage(ImageLoader.getImage(
- ImageLoader.TRANSFER_CALL_BUTTON));
- }
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/call/VolumeControlSlider.java b/src/net/java/sip/communicator/impl/gui/main/call/VolumeControlSlider.java
index 9f8d2f2..e6e19d0 100644
--- a/src/net/java/sip/communicator/impl/gui/main/call/VolumeControlSlider.java
+++ b/src/net/java/sip/communicator/impl/gui/main/call/VolumeControlSlider.java
@@ -22,7 +22,7 @@ import org.jitsi.service.neomedia.event.*;
* @author Yana Stamcheva
*/
public class VolumeControlSlider
- extends SIPCommPopupMenu
+ extends TransparentPanel
implements VolumeChangeListener
{
private final JSlider volumeSlider;
@@ -41,12 +41,19 @@ public class VolumeControlSlider
* @param volumeControl the <tt>VolumeControl</tt> that do the actual volume
* adjusting.
*/
- public VolumeControlSlider(final VolumeControl volumeControl)
+ public VolumeControlSlider( final VolumeControl volumeControl,
+ int orientation)
{
+ super(new BorderLayout());
+
volumeControl.addVolumeChangeListener(this);
- volumeSlider = new JSlider(JSlider.VERTICAL, 0, 100, 50);
- volumeSlider.setPreferredSize(new Dimension(20, 100));
+ volumeSlider = new JSlider(orientation, 0, 100, 50);
+
+ if (orientation == JSlider.VERTICAL)
+ volumeSlider.setPreferredSize(new Dimension(20, 100));
+ else
+ volumeSlider.setPreferredSize(new Dimension(100, 20));
// Sets the minimum, maximum and default volume values for the volume
// slider.
@@ -83,4 +90,18 @@ public class VolumeControlSlider
if (volumeSlider.getValue() != newValue)
volumeSlider.setValue(newValue);
}
+
+ /**
+ * Returns this slider in a popup menu.
+ *
+ * @return this slider in a popup menu
+ */
+ public JPopupMenu getPopupMenu()
+ {
+ SIPCommPopupMenu popupMenu = new SIPCommPopupMenu();
+
+ popupMenu.add(this);
+
+ return popupMenu;
+ }
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationComponent.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationComponent.java
index e25a9af..2191697 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationComponent.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationComponent.java
@@ -296,7 +296,7 @@ public abstract class ChatConversationComponent
*/
public String getDateString(Date date)
{
- return ChatConversationPanel.getDateString(date.getTime())
+ return ChatHtmlUtils.getDateString(date.getTime())
+ GuiUtils.formatTime(date)
+ " ";
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java
index fba0eee..3ec57fa 100755
--- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatConversationPanel.java
@@ -23,11 +23,11 @@ import javax.swing.text.html.*;
import javax.swing.text.html.HTML.*;
import net.java.sip.communicator.impl.gui.*;
-import net.java.sip.communicator.impl.gui.customcontrols.*;
import net.java.sip.communicator.impl.gui.main.chat.history.*;
import net.java.sip.communicator.impl.gui.main.chat.menus.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.gui.*;
+import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.replacement.*;
import net.java.sip.communicator.service.replacement.smilies.*;
import net.java.sip.communicator.util.*;
@@ -61,16 +61,6 @@ public class ChatConversationPanel
= Logger.getLogger(ChatConversationPanel.class);
/**
- * The closing tag of the <code>PLAINTEXT</code> HTML element.
- */
- private static final String END_PLAINTEXT_TAG = "</PLAINTEXT>";
-
- /**
- * The opening tag of the <code>PLAINTEXT</code> HTML element.
- */
- private static final String START_PLAINTEXT_TAG = "<PLAINTEXT>";
-
- /**
* The regular expression (in the form of compiled <tt>Pattern</tt>) which
* matches URLs for the purposed of turning them into links.
*/
@@ -141,19 +131,14 @@ public class ChatConversationPanel
private long lastIncomingMsgTimestamp;
/**
- * Indicates if this component is rendering a history conversation.
+ * The timestamp of the last message.
*/
- private final boolean isHistory;
+ private long lastMessageTimestamp;
/**
- * The html text content type.
- */
- public static final String HTML_CONTENT_TYPE = "text/html";
-
- /**
- * The plain text content type.
+ * Indicates if this component is rendering a history conversation.
*/
- public static final String TEXT_CONTENT_TYPE = "text/plain";
+ private final boolean isHistory;
/**
* The indicator which determines whether an automatic scroll to the bottom
@@ -161,6 +146,8 @@ public class ChatConversationPanel
*/
private boolean scrollToBottomIsPending = false;
+ private String lastMessageUID = null;
+
/**
* The implementation of the routine which scrolls {@link #chatTextPane} to its
* bottom.
@@ -339,32 +326,6 @@ public class ChatConversationPanel
}
/**
- * Initializes the editor by adding a header containing the date.
- * TODO: remove if not used anymore
- */
-// private void initEditor()
-// {
-// Element root = this.document.getDefaultRootElement();
-//
-// Date date = new Date(System.currentTimeMillis());
-//
-// String chatHeader = "<h1>" + GuiUtils.formatDate(date) + " " + "</h1>";
-//
-// try
-// {
-// this.document.insertAfterStart(root, chatHeader);
-// }
-// catch (BadLocationException e)
-// {
-// logger.error("Insert in the HTMLDocument failed.", e);
-// }
-// catch (IOException e)
-// {
-// logger.error("Insert in the HTMLDocument failed.", e);
-// }
-// }
-
- /**
* Retrieves the contents of the sent message with the given ID.
*
* @param messageUID The ID of the message to retrieve.
@@ -373,7 +334,11 @@ public class ChatConversationPanel
public String getMessageContents(String messageUID)
{
Element root = document.getDefaultRootElement();
- Element e = document.getElement(root, Attribute.ID, messageUID);
+ Element e = document.getElement(
+ root,
+ Attribute.ID,
+ ChatHtmlUtils.MESSAGE_TEXT_ID + messageUID);
+
if (e == null)
{
logger.warn("Could not find message with ID" + messageUID);
@@ -395,38 +360,6 @@ public class ChatConversationPanel
}
/**
- * Creates a tag that shows the last edit time of a message, in the format
- * (Edited at ...).
- * If <tt>date < 0</tt>, returns an empty tag that serves as a placeholder
- * for future corrections of this message.
- *
- * @param messageUID The ID of the edited message.
- * @param date The date when the message was last edited, or -1 to generate
- * an empty tag.
- * @return The string representation of the tag.
- */
- private String generateEditedAtTag(String messageUID, long date)
- {
- StringBuilder res = new StringBuilder();
- // Use a <cite /> tag here as most of the other inline tags (e.g. h1-7,
- // b, i) cause different problems when used in setOuterHTML.
- res.append("<cite id='");
- res.append(messageUID);
- res.append("-editedAt'> ");
- if (date > 0)
- {
- res.append("&nbsp;");
- String contents = GuiActivator.getResources().getI18NString(
- "service.gui.EDITED_AT",
- new String[] { GuiUtils.formatTime(date) }
- );
- res.append(contents);
- }
- res.append("</cite>");
- return res.toString();
- }
-
- /**
* Processes the message given by the parameters.
*
* @param chatMessage the message
@@ -434,8 +367,20 @@ public class ChatConversationPanel
* display of <tt>chatMessage</tt> in the UI
* @return the processed message
*/
- public String processMessage(ChatMessage chatMessage, String keyword)
+ public String processMessage( ChatMessage chatMessage,
+ String keyword,
+ ProtocolProviderService protocolProvider,
+ String contactAddress)
{
+ String contentType = chatMessage.getContentType();
+
+ // If this is a consecutive message don't go through the initiation
+ // and just append it.
+ if (appendConsecutiveMessage(chatMessage, keyword, contentType))
+ return null;
+
+ lastMessageTimestamp = chatMessage.getDate();
+
String contactName = chatMessage.getContactName();
String contactDisplayName = chatMessage.getContactDisplayName();
if (contactDisplayName == null
@@ -445,99 +390,88 @@ public class ChatConversationPanel
{
// for some reason &apos; is not rendered correctly from our ui,
// lets use its equivalent. Other similar chars(< > & ") seem ok.
- contactDisplayName = contactDisplayName.replaceAll("&apos;", "&#39;");
+ contactDisplayName
+ = contactDisplayName.replaceAll("&apos;", "&#39;");
}
- String contentType = chatMessage.getContentType();
long date = chatMessage.getDate();
String messageType = chatMessage.getMessageType();
String messageTitle = chatMessage.getMessageTitle();
- String message = chatMessage.getMessage();
String messageUID = chatMessage.getMessageUID();
-
- String msgID = "message";
- String msgHeaderID = "messageHeader";
+ String message = chatMessage.getMessage();
+ String msgID = ChatHtmlUtils.MESSAGE_TEXT_ID + messageUID;
String chatString = "";
String endHeaderTag = "";
- String dateString = getDateString(date);
- String idAttr = messageUID == null ? "" : " id='" + messageUID + "'";
- String dateAttr = " date='" + date + "'";
- String editedAtTag = generateEditedAtTag(messageUID, -1);
-
- String startDivTag = "<DIV identifier=\"" + msgID + "\"" + idAttr + ">";
- String startHistoryDivTag
- = "<DIV identifier=\"" + msgID + "\" style=\"color:#707070;\">";
+
String startSystemDivTag
= "<DIV identifier=\"systemMessage\" style=\"color:#627EB7;\">";
String endDivTag = "</DIV>";
- String startPlainTextTag;
- String endPlainTextTag;
+ lastMessageUID = messageUID;
- if (HTML_CONTENT_TYPE.equals(contentType))
+ String startPlainTextTag
+ = ChatHtmlUtils.createStartPlainTextTag(contentType);
+ String endPlainTextTag
+ = ChatHtmlUtils.createEndPlainTextTag(contentType);
+
+ if (messageType.equals(Chat.INCOMING_MESSAGE))
{
- startPlainTextTag = "";
- endPlainTextTag = "";
+ this.lastIncomingMsgTimestamp = System.currentTimeMillis();
+
+ chatString = ChatHtmlUtils.createIncomingMessageTag(
+ msgID,
+ contactName,
+ contactDisplayName,
+ getContactAvatar(protocolProvider, contactAddress),
+ date,
+ formatMessage(message, contentType, keyword),
+ contentType);
}
- else
+ else if (messageType.equals(Chat.OUTGOING_MESSAGE))
{
- startPlainTextTag = START_PLAINTEXT_TAG;
- endPlainTextTag = END_PLAINTEXT_TAG;
+ chatString = ChatHtmlUtils.createOutgoingMessageTag(
+ msgID,
+ contactName,
+ contactDisplayName,
+ getContactAvatar(protocolProvider),
+ date,
+ formatMessage(message, contentType, keyword),
+ contentType);
}
-
- if (messageType.equals(Chat.INCOMING_MESSAGE))
+ else if (messageType.equals(Chat.HISTORY_INCOMING_MESSAGE))
{
this.lastIncomingMsgTimestamp = System.currentTimeMillis();
- chatString = "<h2 identifier=\"" + msgHeaderID + "\""
- + dateAttr + ">"
- + "<a style=\"color:#ef7b1e;"
- + "font-weight:bold;"
- + "text-decoration:none;\" "
- + "href=\"" + contactName + "\">";
-
- endHeaderTag = "</a></h2>";
-
- chatString
- += dateString + contactDisplayName + " at "
- + GuiUtils.formatTime(date) + editedAtTag + endHeaderTag
- + startDivTag + startPlainTextTag
- + formatMessage(message, contentType, keyword)
- + endPlainTextTag + endDivTag;
+ chatString = ChatHtmlUtils.createIncomingMessageTag(
+ msgID,
+ contactName,
+ contactDisplayName,
+ getContactAvatar(protocolProvider, contactAddress),
+ date,
+ formatMessage(message, contentType, keyword),
+ contentType);
}
- else if (messageType.equals(Chat.SMS_MESSAGE))
+ else if (messageType.equals(Chat.HISTORY_OUTGOING_MESSAGE))
{
- chatString = "<h2 identifier=\""
- + msgHeaderID
- + "\" date=\""
- + date + "\">";
-
- endHeaderTag = "</h2>";
-
- chatString
- += "SMS: " + dateString + contactName + " at "
- + GuiUtils.formatTime(date) + endHeaderTag + startDivTag
- + startPlainTextTag
- + formatMessage(message, contentType, keyword)
- + endPlainTextTag + endDivTag;
+ chatString = ChatHtmlUtils.createOutgoingMessageTag(
+ msgID,
+ contactName,
+ contactDisplayName,
+ getContactAvatar(protocolProvider),
+ date,
+ formatMessage(message, contentType, keyword),
+ contentType);
}
- else if (messageType.equals(Chat.OUTGOING_MESSAGE))
+ else if (messageType.equals(Chat.SMS_MESSAGE))
{
- chatString = "<h3 identifier=\"" + msgHeaderID + "\""
- + dateAttr + ">"
- + "<a style=\"color:#2e538b;"
- + "font-weight:bold;"
- + "text-decoration:none;\" "
- + "href=\"" + contactName + "\">";
-
- endHeaderTag = "</a></h3>";
-
- chatString
- += dateString + contactDisplayName + " at "
- + GuiUtils.formatTime(date) + editedAtTag + endHeaderTag
- + startDivTag + startPlainTextTag
- + formatMessage(message, contentType, keyword)
- + endPlainTextTag + endDivTag;
+ chatString = ChatHtmlUtils.createIncomingMessageTag(
+ msgID,
+ contactName,
+ contactDisplayName,
+ getContactAvatar(protocolProvider, contactAddress),
+ date,
+ formatMessage("SMS: " + message, contentType, keyword),
+ contentType);
}
else if (messageType.equals(Chat.STATUS_MESSAGE))
{
@@ -570,7 +504,7 @@ public class ChatConversationPanel
else if (messageType.equals(Chat.ERROR_MESSAGE))
{
chatString = "<h6 identifier=\""
- + msgHeaderID
+ + ChatHtmlUtils.MESSAGE_HEADER_ID
+ "\" date=\""
+ date + "\">";
@@ -584,43 +518,6 @@ public class ChatConversationPanel
+ messageTitle
+ endHeaderTag + "<h5>" + message + "</h5>";
}
- else if (messageType.equals(Chat.HISTORY_INCOMING_MESSAGE))
- {
- chatString = "<h2 identifier=\"" + msgHeaderID + "\""
- + dateAttr + ">"
- + "<a style=\"color:#ef7b1e;"
- + "font-weight:bold;"
- + "text-decoration:none;\" "
- + "href=\"" + contactName + "\">";
-
- endHeaderTag = "</a></h2>";
-
- chatString
- += dateString + contactDisplayName
- + " at " + GuiUtils.formatTime(date) + endHeaderTag
- + editedAtTag + startHistoryDivTag + startPlainTextTag
- + formatMessage(message, contentType, keyword)
- + endPlainTextTag + endDivTag;
- }
- else if (messageType.equals(Chat.HISTORY_OUTGOING_MESSAGE))
- {
- chatString = "<h3 identifier=\"" + msgHeaderID + "\""
- + dateAttr + ">"
- + "<a style=\"color:#2e538b;"
- + "font-weight:bold;"
- + "text-decoration:none;\" "
- + "href=\"" + contactName + "\">";
-
- endHeaderTag = "</h3>";
-
- chatString
- += dateString
- + contactDisplayName + " at " + GuiUtils.formatTime(date)
- + editedAtTag + endHeaderTag
- + startHistoryDivTag + startPlainTextTag
- + formatMessage(message, contentType, keyword)
- + endPlainTextTag + endDivTag;
- }
return chatString;
}
@@ -631,9 +528,91 @@ public class ChatConversationPanel
* @param chatMessage the message.
* @return the formatted message
*/
- public String processMessage(ChatMessage chatMessage)
+ public String processMessage( ChatMessage chatMessage,
+ ProtocolProviderService protocolProvider,
+ String contactAddress)
+ {
+ return processMessage( chatMessage,
+ null,
+ protocolProvider,
+ contactAddress);
+ }
+
+ /**
+ * Appends a consecutive message to the document.
+ *
+ * @param chatMessage the message to append
+ * @return <tt>true</tt> if the append succeeded, <tt>false</tt> - otherwise
+ */
+ public boolean appendConsecutiveMessage(ChatMessage chatMessage,
+ String keyword,
+ String contentType)
{
- return processMessage(chatMessage, null);
+ if (lastMessageUID == null)
+ return false;
+
+ Element root = document.getDefaultRootElement();
+ Element lastMsgElement = document.getElement(root, Attribute.ID,
+ ChatHtmlUtils.MESSAGE_TEXT_ID + lastMessageUID);
+
+ if (lastMsgElement == null)
+ {
+ logger.warn("Could not find message with ID " + lastMessageUID);
+ return false;
+ }
+
+ String contactAddress
+ = (String) lastMsgElement.getAttributes()
+ .getAttribute(Attribute.NAME);
+
+ if (contactAddress != null
+ && contactAddress.equals(chatMessage.getContactName())
+ // And if the new message is within a minute from the last one.
+ && (chatMessage.getDate() - lastMessageTimestamp
+ < 60000))
+ {
+ String newMessage = ChatHtmlUtils.createMessageTag(
+ ChatHtmlUtils.MESSAGE_TEXT_ID
+ + chatMessage.getMessageUID(),
+ contactAddress,
+ formatMessage(chatMessage.getMessage(),
+ contentType,
+ keyword),
+ contentType,
+ chatMessage.getDate(),
+ false);
+
+ synchronized (scrollToBottomRunnable)
+ {
+ try
+ {
+ Element parentElement = lastMsgElement.getParentElement();
+
+ document.insertBeforeEnd(parentElement, newMessage);
+
+ lastMessageUID = chatMessage.getMessageUID();
+
+ // Need to call explicitly scrollToBottom, because for some
+ // reason the componentResized event isn't fired every time
+ // we add text.
+ SwingUtilities.invokeLater(scrollToBottomRunnable);
+ }
+ catch (BadLocationException ex)
+ {
+ logger.error("Could not replace chat message", ex);
+ }
+ catch (IOException ex)
+ {
+ logger.error("Could not replace chat message", ex);
+ }
+ }
+
+ finishMessageAdd(newMessage, contentType);
+
+ return true;
+ }
+
+ return false;
}
/**
@@ -647,82 +626,78 @@ public class ChatConversationPanel
{
String correctedUID = chatMessage.getCorrectedMessageUID();
Element root = document.getDefaultRootElement();
- Element e = document.getElement(root, Attribute.ID, correctedUID);
- if (e == null)
+ Element correctedMsgElement
+ = document.getElement(root,
+ Attribute.ID,
+ ChatHtmlUtils.MESSAGE_TEXT_ID + correctedUID);
+
+ if (correctedMsgElement == null)
{
logger.warn("Could not find message with ID " + correctedUID);
return;
}
- int len = e.getEndOffset() - e.getStartOffset();
-
- StringBuilder newContents = new StringBuilder();
- String bgColor = GuiActivator.getResources().getColorString(
- "service.gui.CHAT_EDIT_MESSAGE_BACKGROUND");
- newContents.append("<div identifier='message' id='");
- newContents.append(chatMessage.getMessageUID());
- newContents.append("' bgcolor='");
- newContents.append(bgColor);
- newContents.append("'>");
- if (chatMessage.getContentType().equals(TEXT_CONTENT_TYPE))
- {
- newContents.append(START_PLAINTEXT_TAG);
- newContents.append(chatMessage.getMessage());
- newContents.append(END_PLAINTEXT_TAG);
- }
- else
- {
- newContents.append(chatMessage.getMessage());
- }
- newContents.append("</div>");
-
- Element header = document.getElement(root, Attribute.ID,
- correctedUID + "-editedAt");
-
- try
+
+ String contactAddress
+ = (String) correctedMsgElement.getAttributes()
+ .getAttribute(Attribute.NAME);
+
+ String newMessage = ChatHtmlUtils.createMessageTag(
+ ChatHtmlUtils.MESSAGE_TEXT_ID
+ + chatMessage.getMessageUID(),
+ contactAddress,
+ formatMessage( chatMessage.getMessage(),
+ chatMessage.getContentType(),
+ ""),
+ chatMessage.getContentType(),
+ chatMessage.getDate(),
+ true);
+
+ synchronized (scrollToBottomRunnable)
{
- if (header != null)
+ try
{
- String newHeaderContents = generateEditedAtTag(
- chatMessage.getMessageUID(), chatMessage.getDate());
- document.setOuterHTML(header, newHeaderContents);
+ document.setOuterHTML(correctedMsgElement, newMessage);
+
+ lastMessageUID = chatMessage.getMessageUID();
+
+ // Need to call explicitly scrollToBottom, because for some
+ // reason the componentResized event isn't fired every time
+ // we add text.
+ SwingUtilities.invokeLater(scrollToBottomRunnable);
+ }
+ catch (BadLocationException ex)
+ {
+ logger.error("Could not replace chat message", ex);
+ }
+ catch (IOException ex)
+ {
+ logger.error("Could not replace chat message", ex);
}
- document.setOuterHTML(e, newContents.toString());
- }
- catch (BadLocationException ex)
- {
- logger.error("Could not replace chat message", ex);
- }
- catch (IOException ex)
- {
- logger.error("Could not replace chat message", ex);
}
+
+ finishMessageAdd(newMessage, chatMessage.getContentType());
}
/**
* Appends the given string at the end of the contained in this panel
* document.
*
- * @param chatString the string to append
+ * @param message the message string to append
*/
- public void appendMessageToEnd(String chatString, String contentType)
+ public void appendMessageToEnd(String message, String contentType)
{
+ if (message == null)
+ return;
+
synchronized (scrollToBottomRunnable)
{
Element root = document.getDefaultRootElement();
-// Need to call explicitly scrollToBottom, because for some
-// reason the componentResized event isn't fired every time we
-// add text.
-// Replaced by the code on line: 573.
-//
-// scrollToBottomIsPending = true;
-
try
{
- document
- .insertAfterEnd(
- root.getElement(root.getElementCount() - 1),
- chatString);
+ document.insertAfterEnd(
+ root.getElement(root.getElementCount() - 1),
+ message);
// Need to call explicitly scrollToBottom, because for some
// reason the componentResized event isn't fired every time we
@@ -737,33 +712,44 @@ public class ChatConversationPanel
{
logger.error("Insert in the HTMLDocument failed.", e);
}
- if (!isHistory)
- ensureDocumentSize();
+ }
- // Process replacements.
- final Element elem;
- /*
- * Check to make sure element isn't the first element in the HTML
- * document.
- */
- if (!(root.getElementCount() < 2))
- {
- elem = root.getElement(root.getElementCount() - 2);
- }
- else
- elem = root.getElement(1);
+ finishMessageAdd(message, contentType);
+ }
- /*
- * Replacements will be processed only if it is enabled in the
- * property
- */
- if (GuiActivator.getConfigurationService().getBoolean(
- ReplacementProperty.REPLACEMENT_ENABLE, true)
- || GuiActivator.getConfigurationService().getBoolean(
- ReplacementProperty.getPropertyName("SMILEY"), true))
- {
- processReplacement(elem, chatString, contentType);
- }
+ /**
+ * Performs all operations needed in order to finish the adding of the
+ * message to the document.
+ *
+ * @param message the message string
+ * @param contentType
+ */
+ private void finishMessageAdd(String message, String contentType)
+ {
+ Element root = document.getDefaultRootElement();
+
+ // If we're not in chat history case we need to be sure the document
+ // has not exceeded the required size (number of messages).
+ if (!isHistory)
+ ensureDocumentSize();
+
+ /*
+ * Check to make sure element isn't the first element in the HTML
+ * document.
+ */
+ Element elem = document.getElement(root, Attribute.ID,
+ ChatHtmlUtils.MESSAGE_TEXT_ID + lastMessageUID);
+
+ /*
+ * Replacements will be processed only if it is enabled in the
+ * property.
+ */
+ if (GuiActivator.getConfigurationService().getBoolean(
+ ReplacementProperty.REPLACEMENT_ENABLE, true)
+ || GuiActivator.getConfigurationService().getBoolean(
+ ReplacementProperty.getPropertyName("SMILEY"), true))
+ {
+ processReplacement(elem, message, contentType);
}
}
@@ -818,15 +804,6 @@ public class ChatConversationPanel
Matcher m = p.matcher(msgStore);
- String startPlainTextTag = "";
- String endPlainTextTag = "";
-
- if (!HTML_CONTENT_TYPE.equals(contentType))
- {
- startPlainTextTag = START_PLAINTEXT_TAG;
- endPlainTextTag = END_PLAINTEXT_TAG;
- }
-
int count = 0, startPos = 0;
StringBuffer msgBuff = new StringBuffer();
@@ -843,7 +820,9 @@ public class ChatConversationPanel
{
if(isSmiley)
{
- msgBuff.append(endPlainTextTag);
+ msgBuff.append(
+ ChatHtmlUtils.createEndPlainTextTag(
+ contentType));
msgBuff.append("<IMG SRC=\"");
}
else
@@ -858,7 +837,9 @@ public class ChatConversationPanel
msgBuff.append("\"></IMG>");
if(isSmiley)
- msgBuff.append(startPlainTextTag);
+ msgBuff.append(
+ ChatHtmlUtils.createStartPlainTextTag(
+ contentType));
}
else
{
@@ -884,8 +865,12 @@ public class ChatConversationPanel
synchronized (scrollToBottomRunnable)
{
scrollToBottomIsPending = true;
+
+ int msgStartIndex = msgStore.indexOf("<div id");
document.setOuterHTML(elem, msgStore.toString()
- .substring(msgStore.indexOf("<DIV")));
+ .substring(
+ msgStartIndex,
+ msgStore.indexOf("</div>", msgStartIndex)));
}
}
return "";
@@ -916,7 +901,7 @@ public class ChatConversationPanel
.getAttributes().getAttribute("identifier");
if(idAttr != null
- && (idAttr.equals("message")
+ && (idAttr.startsWith(ChatHtmlUtils.MESSAGE_TEXT_ID)
|| idAttr.equals("statusMessage")
|| idAttr.equals("systemMessage")))
{
@@ -940,7 +925,8 @@ public class ChatConversationPanel
// Remove the header of the message if such exists.
if(firstMsgIndex > 0)
{
- Element headerElement = rootElement.getElement(firstMsgIndex - 1);
+ Element headerElement
+ = rootElement.getElement(firstMsgIndex - 1);
String idAttr = (String) headerElement
.getAttributes().getAttribute("identifier");
@@ -977,20 +963,6 @@ public class ChatConversationPanel
String contentType,
String keyword)
{
- String startPlainTextTag;
- String endPlainTextTag;
-
- if (HTML_CONTENT_TYPE.equals(contentType))
- {
- startPlainTextTag = "";
- endPlainTextTag = "";
- }
- else
- {
- startPlainTextTag = START_PLAINTEXT_TAG;
- endPlainTextTag = END_PLAINTEXT_TAG;
- }
-
Matcher m
= Pattern.compile(Pattern.quote(keyword), Pattern.CASE_INSENSITIVE)
.matcher(message);
@@ -1004,11 +976,11 @@ public class ChatConversationPanel
String keywordMatch = m.group().trim();
- msgBuffer.append(endPlainTextTag);
+ msgBuffer.append(ChatHtmlUtils.createEndPlainTextTag(contentType));
msgBuffer.append("<b>");
msgBuffer.append(keywordMatch);
msgBuffer.append("</b>");
- msgBuffer.append(startPlainTextTag);
+ msgBuffer.append(ChatHtmlUtils.createStartPlainTextTag(contentType));
}
/*
@@ -1037,7 +1009,7 @@ public class ChatConversationPanel
{
// If the message content type is HTML we won't process links and
// new lines, but only the smileys.
- if (!HTML_CONTENT_TYPE.equals(contentType))
+ if (!ChatHtmlUtils.HTML_CONTENT_TYPE.equals(contentType))
{
/*
@@ -1065,7 +1037,8 @@ public class ChatConversationPanel
message
= processNewLines(
- processLinksAndHTMLChars(message, processHTMLChars));
+ processLinksAndHTMLChars(
+ message, processHTMLChars, contentType), contentType);
}
// If the message content is HTML, we process br and img tags.
else
@@ -1090,10 +1063,12 @@ public class ChatConversationPanel
* @param message The source message string.
* @param processHTMLChars <tt>true</tt> to escape the special HTML chars;
* otherwise, <tt>false</tt>
+ * @param contentType the message content type (html or plain text)
* @return The message string with properly formatted links.
*/
private String processLinksAndHTMLChars(String message,
- boolean processHTMLChars)
+ boolean processHTMLChars,
+ String contentType)
{
Matcher m = URL_PATTERN.matcher(message);
StringBuffer msgBuffer = new StringBuffer();
@@ -1110,7 +1085,7 @@ public class ChatConversationPanel
String url = m.group().trim();
- msgBuffer.append(END_PLAINTEXT_TAG);
+ msgBuffer.append(ChatHtmlUtils.createEndPlainTextTag(contentType));
msgBuffer.append("<A href=\"");
if (url.startsWith("www"))
msgBuffer.append("http://");
@@ -1118,7 +1093,7 @@ public class ChatConversationPanel
msgBuffer.append("\">");
msgBuffer.append(url);
msgBuffer.append("</A>");
- msgBuffer.append(START_PLAINTEXT_TAG);
+ msgBuffer.append(ChatHtmlUtils.createStartPlainTextTag(contentType));
}
String fromPrevEndToEnd = message.substring(prevEnd);
@@ -1151,9 +1126,10 @@ public class ChatConversationPanel
* Formats message new lines.
*
* @param message The source message string.
+ * @param contentType message contentType (html or plain text)
* @return The message string with properly formatted new lines.
*/
- private String processNewLines(String message)
+ private String processNewLines(String message, String contentType)
{
/*
@@ -1171,7 +1147,9 @@ public class ChatConversationPanel
message
.replaceAll(
"\n",
- END_PLAINTEXT_TAG + "<BR/>&#10;" + START_PLAINTEXT_TAG);
+ ChatHtmlUtils.createEndPlainTextTag(contentType)
+ + "<BR/>&#10;"
+ + ChatHtmlUtils.createStartPlainTextTag(contentType));
}
/**
@@ -1508,7 +1486,8 @@ public class ChatConversationPanel
int start = 0;
// while we find some <img /> self-closing tags with a slash inside.
- while(m.find()){
+ while(m.find())
+ {
// First, we have to copy all the message preceding the <img> tag.
processedMessage.append(message.substring(start, m.start()));
// Then, we find the position of the slash inside the tag.
@@ -1577,13 +1556,16 @@ public class ChatConversationPanel
wrapPanel.add(component, BorderLayout.NORTH);
- style
- .addAttribute(StyleConstants.ComponentAttribute, wrapPanel);
+ style.addAttribute(StyleConstants.ComponentAttribute, wrapPanel);
style.addAttribute("identifier", "messageHeader");
style.addAttribute("date", component.getDate().getTime());
scrollToBottomIsPending = true;
+ // We need to reinitialize the last message ID, because we don't
+ // want components to be taken into account.
+ lastMessageUID = null;
+
// Insert the component style at the end of the text
try
{
@@ -1620,26 +1602,6 @@ public class ChatConversationPanel
}
/**
- * Returns the date string to show for the given date.
- *
- * @param date the date to format
- * @return the date string to show for the given date
- */
- public static String getDateString(long date)
- {
- if (GuiUtils.compareDatesOnly(date, System.currentTimeMillis()) < 0)
- {
- StringBuffer dateStrBuf = new StringBuffer();
-
- GuiUtils.formatDate(date, dateStrBuf);
- dateStrBuf.append(" ");
- return dateStrBuf.toString();
- }
-
- return "";
- }
-
- /**
* Reloads images.
*/
public void loadSkin()
@@ -1665,33 +1627,26 @@ public class ChatConversationPanel
{
return processKeyword(message, contentType, keyWord);
}
-
+
+ /**
+ * Processes /me command in group chats.
+ *
+ * @param chatMessage the chat message
+ * @return the newly processed message string
+ */
public String processMeCommand(ChatMessage chatMessage)
{
String contentType = chatMessage.getContentType();
String message = chatMessage.getMessage();
- String msgID = "message";
+ String msgID
+ = ChatHtmlUtils.MESSAGE_TEXT_ID + chatMessage.getMessageUID();
String chatString = "";
String endHeaderTag = "";
- String startDivTag = "<DIV identifier=\"" + msgID + "\">";
+ String startDivTag = "<DIV id=\"" + msgID + "\">";
String endDivTag = "</DIV>";
- String startPlainTextTag;
- String endPlainTextTag;
-
- if (HTML_CONTENT_TYPE.equals(contentType))
- {
- startPlainTextTag = "";
- endPlainTextTag = "";
- }
- else
- {
- startPlainTextTag = START_PLAINTEXT_TAG;
- endPlainTextTag = END_PLAINTEXT_TAG;
- }
-
if (message.length() > 4 && message.substring(0, 4).equals("/me "))
{
chatString = startDivTag + "<B><I>";
@@ -1699,7 +1654,6 @@ public class ChatConversationPanel
endHeaderTag = "</I></B>" + endDivTag;
chatString +=
-
processHTMLChars("*** " + chatMessage.getContactName() + " "
+ message.substring(4))
+ endHeaderTag;
@@ -1731,9 +1685,13 @@ public class ChatConversationPanel
while (m.find())
{
- msgTemp.insert(m.start(), startPlainTextTag);
- msgTemp.insert(m.end() + startPlainTextTag.length(),
- endPlainTextTag);
+ msgTemp.insert(m.start(),
+ ChatHtmlUtils.createStartPlainTextTag(contentType));
+ msgTemp.insert(
+ m.end()
+ + ChatHtmlUtils
+ .createStartPlainTextTag(contentType).length(),
+ ChatHtmlUtils.createEndPlainTextTag(contentType));
}
if (msgTemp.length() != msgStore.length())
@@ -1746,4 +1704,72 @@ public class ChatConversationPanel
else
return "";
}
-}
+
+ /**
+ * Returns the avatar corresponding to the account of the given
+ * <tt>protocolProvider</tt>.
+ *
+ * @param protocolProvider the protocol provider service, which account
+ * avatar we're looking for
+ * @return the avatar corresponding to the account of the given
+ * <tt>protocolProvider</tt>
+ */
+ private static String getContactAvatar(
+ ProtocolProviderService protocolProvider,
+ String contactAddress)
+ {
+ String avatarPath
+ = AvatarCacheUtils.getCachedAvatarPath( protocolProvider,
+ contactAddress);
+
+ File avatarFile;
+ try
+ {
+ avatarFile = GuiActivator.getFileAccessService()
+ .getPrivatePersistentFile(avatarPath);
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+
+ if(avatarFile.exists() && avatarFile.length() > 0)
+ return "file:" + avatarFile.getAbsolutePath();
+ else
+ return GuiActivator.getResources().getImageURL(
+ "service.gui.DEFAULT_USER_PHOTO_SMALL").toString();
+ }
+
+ /**
+ * Returns the avatar corresponding to the account of the given
+ * <tt>protocolProvider</tt>.
+ *
+ * @param protocolProvider the protocol provider service, which account
+ * avatar we're looking for
+ * @return the avatar corresponding to the account of the given
+ * <tt>protocolProvider</tt>
+ */
+ private static String getContactAvatar(
+ ProtocolProviderService protocolProvider)
+ {
+ String avatarPath
+ = AvatarCacheUtils.getCachedAvatarPath(protocolProvider);
+
+ File avatarFile;
+ try
+ {
+ avatarFile = GuiActivator.getFileAccessService()
+ .getPrivatePersistentFile(avatarPath);
+ }
+ catch (Exception e)
+ {
+ return null;
+ }
+
+ if(avatarFile.exists() && avatarFile.length() > 0)
+ return "file:" + avatarFile.getAbsolutePath();
+ else
+ return GuiActivator.getResources().getImageURL(
+ "service.gui.DEFAULT_USER_PHOTO_SMALL").toString();
+ }
+} \ No newline at end of file
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatHtmlUtils.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatHtmlUtils.java
new file mode 100644
index 0000000..98293f3
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatHtmlUtils.java
@@ -0,0 +1,412 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license. See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.gui.main.chat;
+
+import net.java.sip.communicator.impl.gui.*;
+import net.java.sip.communicator.util.*;
+
+/**
+ *
+ * @author Yana Stamcheva
+ */
+public class ChatHtmlUtils
+{
+ /**
+ * The name attribute.
+ */
+ public final static String NAME_ATTRIBUTE = "name";
+
+ /**
+ * The date attribute.
+ */
+ public final static String DATE_ATTRIBUTE = "date";
+
+ /**
+ * The message header identifier attribute.
+ */
+ public final static String MESSAGE_HEADER_ID = "messageHeader";
+
+ /**
+ * The message identifier attribute.
+ */
+ public final static String MESSAGE_TEXT_ID = "message";
+
+ /**
+ * The closing tag of the <code>PLAINTEXT</code> HTML element.
+ */
+ private static final String END_PLAINTEXT_TAG = "</PLAINTEXT>";
+
+ /**
+ * The opening tag of the <code>PLAINTEXT</code> HTML element.
+ */
+ private static final String START_PLAINTEXT_TAG = "<PLAINTEXT>";
+
+ /**
+ * The html text content type.
+ */
+ public static final String HTML_CONTENT_TYPE = "text/html";
+
+ /**
+ * The plain text content type.
+ */
+ public static final String TEXT_CONTENT_TYPE = "text/plain";
+
+ /**
+ * Creates an incoming message tag.
+ *
+ * @param messageID the identifier
+ * @param contactName the name of the contact sending the message
+ * @param contactDisplayName the display name of the contact sending the
+ * message
+ * @param avatarPath the path to the avatar file
+ * @param date the date, when the message was sent
+ * @param message the message content
+ * @param contentType the content type HTML or PLAIN_TEXT
+ * @return the created incoming message tag
+ */
+ public static String createIncomingMessageTag(
+ String messageID,
+ String contactName,
+ String contactDisplayName,
+ String avatarPath,
+ long date,
+ String message,
+ String contentType)
+ {
+ StringBuffer headerBuffer = new StringBuffer();
+
+ headerBuffer.append("<h2 identifier=\"" + MESSAGE_HEADER_ID + "\" ");
+ headerBuffer.append(DATE_ATTRIBUTE + "='" + date + "'" + ">");
+ headerBuffer.append("<a style=\"color:#488fe7;");
+ headerBuffer.append("font-weight:bold;");
+ headerBuffer.append("text-decoration:none;\" ");
+ headerBuffer.append("href=\"" + contactName + "\">");
+ headerBuffer.append(
+ contactDisplayName + createEditedAtTag(messageID, -1));
+ headerBuffer.append("</a></h2>");
+
+ StringBuffer messageBuff = new StringBuffer();
+
+ messageBuff.append("<div "
+ + IncomingMessageStyle.createMessageStyle() + ">");
+ messageBuff.append("<table width=\"100%\">");
+ messageBuff.append("<tr>");
+ messageBuff.append("<td valign=\"top\">");
+ messageBuff.append(
+ "<table " + IncomingMessageStyle.createTableBubbleStyle()
+ + " cellspacing=\"0px\" cellpadding=\"0px\">");
+ messageBuff.append("<tr>");
+ messageBuff.append("<td style=\"width:26px;\"></td>");
+ messageBuff.append("<td style=\"width:9px;\"></td>");
+ messageBuff.append("<td "
+ + IncomingMessageStyle.createTableBubbleTlStyle() + ">");
+ messageBuff.append(
+ createMessageTableTag(headerBuffer.toString(), date));
+ messageBuff.append("</td>");
+ messageBuff.append("<td "
+ + IncomingMessageStyle.createTableBubbleTrStyle() + "></td>");
+ messageBuff.append("</tr>");
+
+ // Third row.
+ messageBuff.append("<tr>");
+ messageBuff.append("<td><img src=\"" + avatarPath
+ + "\" width=\"26px\" height=\"26px\"/> </td>");
+ messageBuff.append("<td "
+ + IncomingMessageStyle.createIndicatorStyle() +"></td>");
+ messageBuff.append("<td "
+ + IncomingMessageStyle.createTableBubbleMessageStyle() + ">");
+
+ messageBuff.append(
+ createMessageTag( messageID,
+ contactName,
+ message,
+ contentType,
+ date,
+ false));
+
+ messageBuff.append("</td>");
+ messageBuff.append("<td "
+ + IncomingMessageStyle.createTableBubbleMessageRightStyle()
+ + "></td>");
+ messageBuff.append("</tr>");
+
+ //Forth row.
+ messageBuff.append("<tr>");
+ messageBuff.append("<td style=\"width:26px;\"></td>");
+ messageBuff.append("<td style=\"width:9px;\"></td>");
+ messageBuff.append("<td "
+ + IncomingMessageStyle.createTableBubbleBlStyle() + "></td>");
+ messageBuff.append("<td "
+ + IncomingMessageStyle.createTableBubbleBrStyle() + "></td>");
+ messageBuff.append("</tr>");
+
+ messageBuff.append("</table>");
+ messageBuff.append("</td>");
+ messageBuff.append("</tr>");
+ messageBuff.append("</table>");
+ messageBuff.append("</div>");
+
+ return messageBuff.toString();
+ }
+
+ /**
+ * Create an outgoing message tag.
+ *
+ * @param messageID the identifier of the message
+ * @param contactName the name of the account sending the message
+ * @param contactDisplayName the display name of the account sending the
+ * message
+ * @param avatarPath the path to the avatar image
+ * @param date the date, when the message was sent
+ * @param message the content of the message
+ * @param contentType the content type HTML or PLAIN_TEXT
+ * @return the created outgoing message tag
+ */
+ public static String createOutgoingMessageTag( String messageID,
+ String contactName,
+ String contactDisplayName,
+ String avatarPath,
+ long date,
+ String message,
+ String contentType)
+ {
+ StringBuffer headerBuffer = new StringBuffer();
+
+ headerBuffer.append("<h3 identifier=\"" + MESSAGE_HEADER_ID + "\"");
+ headerBuffer.append(DATE_ATTRIBUTE + "='" + date + "'" + ">");
+ headerBuffer.append("<a style=\"color:#6a6868;");
+ headerBuffer.append("font-weight:bold;");
+ headerBuffer.append("float:left;");
+ headerBuffer.append("text-decoration:none;\" ");
+ headerBuffer.append("href=\"" + contactName + "\">");
+ headerBuffer.append(contactDisplayName
+ + createEditedAtTag(messageID, -1));
+ headerBuffer.append("</a></h3>");
+
+ StringBuffer messageBuff = new StringBuffer();
+
+ messageBuff.append("<div "
+ + OutgoingMessageStyle.createMessageStyle() + ">");
+ messageBuff.append("<table width=\"100%\">");
+ messageBuff.append("<tr>");
+ messageBuff.append("<td valign=\"top\">");
+ messageBuff.append(
+ "<table " + OutgoingMessageStyle.createTableBubbleStyle()
+ + " cellspacing=\"0px\" cellpadding=\"0px\">");
+
+ // First row.
+ messageBuff.append("<tr>");
+ messageBuff.append("<td "
+ + OutgoingMessageStyle.createTableBubbleTlStyle() + ">");
+ messageBuff.append(
+ createMessageTableTag(headerBuffer.toString(), date));
+ messageBuff.append("</td>");
+ messageBuff.append("<td "
+ + OutgoingMessageStyle.createTableBubbleTrStyle() + "></td>");
+ messageBuff.append("<td style=\"width:9px;\"></td>");
+ messageBuff.append("<td style=\"width:26px;\"></td>");
+ messageBuff.append("</tr>");
+
+ // Third row.
+ messageBuff.append("<tr>");
+ messageBuff.append("<td "
+ + OutgoingMessageStyle.createTableBubbleMessageStyle() + ">");
+
+ messageBuff.append(
+ createMessageTag( messageID,
+ contactName,
+ message,
+ contentType,
+ date,
+ false));
+
+ messageBuff.append("</td>");
+ messageBuff.append("<td "
+ + OutgoingMessageStyle.createTableBubbleMessageRightStyle()
+ + "></td>");
+ messageBuff.append("<td "
+ + OutgoingMessageStyle.createIndicatorStyle() +"></td>");
+ messageBuff.append("<td><div width=\"26px\" height=\"26px\"><img src=\""
+ + avatarPath
+ + "\" width=\"26px\" height=\"26px\"/></div></td>");
+ messageBuff.append("</tr>");
+
+ // Forth row.
+ messageBuff.append("<tr>");
+ messageBuff.append("<td "
+ + OutgoingMessageStyle.createTableBubbleBlStyle() + "></td>");
+ messageBuff.append("<td "
+ + OutgoingMessageStyle.createTableBubbleBrStyle() + "></td>");
+ messageBuff.append("<td style=\"width:9px;\"></td>");
+ messageBuff.append("<td style=\"width:26px;\"></td>");
+ messageBuff.append("</tr>");
+ messageBuff.append("</table>");
+ messageBuff.append("</td>");
+ messageBuff.append("</tr>");
+ messageBuff.append("</table>");
+ messageBuff.append("</div>");
+
+ return messageBuff.toString();
+ }
+
+ /**
+ * Creates a message table tag, representing the message header.
+ *
+ * @param nameHeader the name of the header.
+ * @param date the date, when the message was sent or received
+ * @return the message header tag
+ */
+ public static String createMessageTableTag( String nameHeader,
+ long date)
+ {
+ StringBuffer messageHeader = new StringBuffer();
+
+ messageHeader.append("<table width=\"100%\">");
+ messageHeader.append("<tr>");
+ messageHeader.append("<td nowrap=\"nowrap\">");
+ messageHeader.append(nameHeader);
+ messageHeader.append("</td>");
+ messageHeader.append("<td nowrap=\"nowrap\" "
+ + OutgoingMessageStyle.createDateStyle() + ">");
+ messageHeader.append(getDateString(date));
+ messageHeader.append(GuiUtils.formatTime(date));
+ messageHeader.append("</td>");
+ messageHeader.append("</tr>");
+ messageHeader.append("</table>");
+
+ return messageHeader.toString();
+ }
+
+ /**
+ * Creates the start tag, which indicates that the next text would be plain
+ * text.
+ *
+ * @param contentType the current content type
+ * @return the start plaintext tag
+ */
+ public static String createStartPlainTextTag(String contentType)
+ {
+ if (HTML_CONTENT_TYPE.equals(contentType))
+ {
+ return "";
+ }
+ else
+ {
+ return START_PLAINTEXT_TAG;
+ }
+ }
+
+ /**
+ * Creates the end tag, which indicates that the next text would be plain
+ * text.
+ *
+ * @param contentType the current content type
+ * @return the end plaintext tag
+ */
+ public static String createEndPlainTextTag(String contentType)
+ {
+ if (HTML_CONTENT_TYPE.equals(contentType))
+ {
+ return "";
+ }
+ else
+ {
+ return END_PLAINTEXT_TAG;
+ }
+ }
+
+ /**
+ * Creates a tag that shows the last edit time of a message, in the format
+ * (Edited at ...).
+ * If <tt>date < 0</tt>, returns an empty tag that serves as a placeholder
+ * for future corrections of this message.
+ *
+ * @param messageUID The ID of the edited message.
+ * @param date The date when the message was last edited, or -1 to generate
+ * an empty tag.
+ * @return The string representation of the tag.
+ */
+ public static String createEditedAtTag(String messageUID, long date)
+ {
+ StringBuilder res = new StringBuilder();
+ // Use a <cite /> tag here as most of the other inline tags (e.g. h1-7,
+ // b, i) cause different problems when used in setOuterHTML.
+ res.append("<cite id='");
+ res.append(messageUID);
+ res.append("-editedAt'> ");
+ if (date > 0)
+ {
+ res.append("&nbsp;");
+ String contents = GuiActivator.getResources().getI18NString(
+ "service.gui.EDITED_AT",
+ new String[] { GuiUtils.formatTime(date) }
+ );
+ res.append(contents);
+ }
+ res.append("</cite>");
+ return res.toString();
+ }
+
+ /**
+ * Creates the message tag.
+ *
+ * @param messageID the identifier of the message
+ * @param contactName the name of the sender
+ * @param message the message content
+ * @param contentType the content type (html or plain text)
+ * @param date the date on which the message was sent
+ * @param isEdited indicates if the given message has been edited
+ * @return the newly constructed message tag
+ */
+ public static String createMessageTag( String messageID,
+ String contactName,
+ String message,
+ String contentType,
+ long date,
+ boolean isEdited)
+ {
+ StringBuffer messageTag = new StringBuffer();
+
+ messageTag.append("<div id=\"");
+ messageTag.append(messageID);
+ messageTag.append("\" ");
+ messageTag.append(NAME_ATTRIBUTE + "=\"" + contactName);
+ messageTag.append("\" style=\"padding-left:10px;");
+ if (isEdited)
+ messageTag.append("font-style:italic;\">");
+ else
+ messageTag.append("\">");
+ messageTag.append(createStartPlainTextTag(contentType));
+ messageTag.append(message);
+ if (isEdited)
+ messageTag.append(" (edited at "
+ + GuiUtils.formatTime(date) + ")");
+ messageTag.append(createEndPlainTextTag(contentType));
+ messageTag.append("</div>");
+
+ return messageTag.toString();
+ }
+
+ /**
+ * Returns the date string to show for the given date.
+ *
+ * @param date the date to format
+ * @return the date string to show for the given date
+ */
+ public static String getDateString(long date)
+ {
+ if (GuiUtils.compareDatesOnly(date, System.currentTimeMillis()) <= 0)
+ {
+ StringBuffer dateStrBuf = new StringBuffer();
+
+ GuiUtils.formatDate(date, dateStrBuf);
+ dateStrBuf.append(" ");
+ return dateStrBuf.toString();
+ }
+
+ return "";
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java
index 9cf6f62..d39b7a0 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatPanel.java
@@ -130,8 +130,6 @@ public class ChatPanel
private boolean isHistoryLoaded;
- private int autoDividerLocation = 0;
-
/**
* Stores all active file transfer requests and effective transfers with
* the identifier of the transfer.
@@ -482,7 +480,7 @@ public class ChatPanel
new String[]{evt.getSourceMember().getName(),
getRoleDescription(evt.getNewRole())})
+"</DIV>",
- ChatConversationPanel.HTML_CONTENT_TYPE);
+ ChatHtmlUtils.HTML_CONTENT_TYPE);
}
/**
@@ -497,7 +495,7 @@ public class ChatPanel
+GuiActivator.getResources().getI18NString("service.gui.ARE_NOW",
new String[]{
getRoleDescription(evt.getNewRole())}) +"</DIV>",
- ChatConversationPanel.HTML_CONTENT_TYPE);
+ ChatHtmlUtils.HTML_CONTENT_TYPE);
}
/**
@@ -687,7 +685,7 @@ public class ChatPanel
if (historyString != null)
conversationPanel.appendMessageToEnd(
- historyString, ChatConversationPanel.TEXT_CONTENT_TYPE);
+ historyString, ChatHtmlUtils.TEXT_CONTENT_TYPE);
}
fireChatHistoryChange();
@@ -839,6 +837,11 @@ public class ChatPanel
message, "text");
}
+ /**
+ * Displays the given chat message.
+ *
+ * @param chatMessage the chat message to display
+ */
private void displayChatMessage(ChatMessage chatMessage)
{
if (chatMessage.getCorrectedMessageUID() != null
@@ -863,7 +866,9 @@ public class ChatPanel
private void appendChatMessage(ChatMessage chatMessage)
{
String processedMessage
- = this.conversationPanel.processMessage(chatMessage);
+ = this.conversationPanel.processMessage(chatMessage,
+ chatSession.getCurrentChatTransport().getProtocolProvider(),
+ chatSession.getCurrentChatTransport().getName());
if (chatSession instanceof ConferenceChatSession)
{
@@ -963,7 +968,10 @@ public class ChatPanel
messageType, null, message, contentType, messageId, null);
String processedMessage =
- this.conversationPanel.processMessage(chatMessage);
+ this.conversationPanel.processMessage(chatMessage,
+ chatSession.getCurrentChatTransport().getProtocolProvider(),
+ chatSession.getCurrentChatTransport().getName());
+
if (chatSession instanceof ConferenceChatSession)
{
String tempMessage =
@@ -1004,7 +1012,7 @@ public class ChatPanel
public String getTextFromWriteArea(String mimeType)
{
if (mimeType.equals(
- OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE))
+ OperationSetBasicInstantMessaging.DEFAULT_MIME_TYPE))
{
return writeMessagePanel.getText();
}
@@ -2062,7 +2070,7 @@ public class ChatPanel
System.currentTimeMillis(),
Chat.STATUS_MESSAGE,
statusMessage,
- ChatConversationPanel.TEXT_CONTENT_TYPE);
+ ChatHtmlUtils.TEXT_CONTENT_TYPE);
}
/**
@@ -2094,7 +2102,7 @@ public class ChatPanel
"service.gui.CHAT_ROOM_SUBJECT_CHANGED",
new String []{ chatSession.getChatName(),
subject}),
- ChatConversationPanel.TEXT_CONTENT_TYPE);
+ ChatHtmlUtils.TEXT_CONTENT_TYPE);
}
}
@@ -2461,8 +2469,6 @@ public class ChatPanel
{
int dividerLocation = messagePane.getHeight() - location;
- autoDividerLocation = dividerLocation;
-
messagePane.setDividerLocation(dividerLocation);
messagePane.revalidate();
messagePane.repaint();
@@ -2760,8 +2766,7 @@ public class ChatPanel
+ event.getOldValue()
+ " is now known as "
+ event.getNewValue() + "</DIV>",
- ChatConversationPanel.HTML_CONTENT_TYPE);
-
+ ChatHtmlUtils.HTML_CONTENT_TYPE);
}
/**
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatTransport.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatTransport.java
index 12aeedd..fc6561b 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatTransport.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatTransport.java
@@ -35,7 +35,7 @@ public interface ChatTransport
* messaging, otherwise returns <code>false</code>
*/
public boolean allowsInstantMessage();
-
+
/**
* Returns <tt>true</tt> if this chat transport supports message
* corrections and false otherwise.
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/ChatWritePanel.java b/src/net/java/sip/communicator/impl/gui/main/chat/ChatWritePanel.java
index 7cdb61f..160515b 100755
--- a/src/net/java/sip/communicator/impl/gui/main/chat/ChatWritePanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/ChatWritePanel.java
@@ -18,7 +18,6 @@ import javax.swing.text.html.*;
import javax.swing.undo.*;
import net.java.sip.communicator.impl.gui.*;
-import net.java.sip.communicator.impl.gui.customcontrols.*;
import net.java.sip.communicator.impl.gui.main.chat.conference.*;
import net.java.sip.communicator.impl.gui.main.chat.menus.*;
import net.java.sip.communicator.impl.gui.utils.*;
@@ -654,7 +653,7 @@ public class ChatWritePanel
chatPanel.getChatConversationPanel()
.appendMessageToEnd(contactList,
- ChatConversationPanel.HTML_CONTENT_TYPE);
+ ChatHtmlUtils.HTML_CONTENT_TYPE);
}
else if(contacts.size() == 1)
{
@@ -963,7 +962,7 @@ public class ChatWritePanel
GuiActivator.getResources().
getI18NString("service.gui.MSG_NOT_POSSIBLE") +
"</h5>",
- ChatConversationPanel.HTML_CONTENT_TYPE);
+ ChatHtmlUtils.HTML_CONTENT_TYPE);
}
else
{
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/IncomingMessageStyle.java b/src/net/java/sip/communicator/impl/gui/main/chat/IncomingMessageStyle.java
new file mode 100644
index 0000000..e6e5b4e
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/IncomingMessageStyle.java
@@ -0,0 +1,203 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.gui.main.chat;
+
+import net.java.sip.communicator.impl.gui.*;
+
+/**
+ * Defines the CSS style of an incoming chat message elements.
+ *
+ * @author Yana Stamcheva
+ */
+public class IncomingMessageStyle
+{
+ /**
+ * The incoming message background image path.
+ */
+ private final static String INCOMING_MESSAGE_IMAGE_PATH
+ = GuiActivator.getResources().getImageURL(
+ "service.gui.lookandfeel.INCOMING_MESSAGE_BACKGROUND").toString();
+
+ /**
+ * The incoming message right image path.
+ */
+ private final static String INCOMING_MESSAGE_IMAGE_RIGHT_PATH
+ = GuiActivator.getResources().getImageURL(
+ "service.gui.lookandfeel.INCOMING_MESSAGE_BACKGROUND_RIGHT")
+ .toString();
+
+ /**
+ * The incoming message indicator image path.
+ */
+ private final static String INCOMING_MESSAGE_INDICATOR_PATH
+ = GuiActivator.getResources().getImageURL(
+ "service.gui.lookandfeel.INCOMING_MESSAGE_INDICATOR").toString();
+
+ /**
+ * The incoming message round border image path.
+ */
+ private final static String INCOMING_MESSAGE_CURVES_PATH
+ = GuiActivator.getResources().getImageURL(
+ "service.gui.lookandfeel.INCOMING_MESSAGE_CURVES").toString();
+
+ /**
+ * The incoming message top image path.
+ */
+ private final static String INCOMING_MESSAGE_CURVES_TOP_PATH
+ = GuiActivator.getResources().getImageURL(
+ "service.gui.lookandfeel.INCOMING_MESSAGE_CURVES_TOP").toString();
+
+ /**
+ * Creates the global message style.
+ *
+ * @return the style attribute defining the global message style.
+ */
+ public static String createMessageStyle()
+ {
+ return "style=\""
+ + "width:100%;"
+ + "opacity:0.96;"
+ + "\"";
+ }
+
+ /**
+ * Creates the style of the table bubble right element.
+ *
+ * @return the style of the table bubble right element
+ */
+ public static String createTableBubbleMessageRightStyle()
+ {
+ return "style=\""
+ + "width:8px;"
+ + " background-image: url('"
+ +INCOMING_MESSAGE_IMAGE_RIGHT_PATH+"');"
+ + " background-repeat: repeat-y;"
+ + " background-position: top left;"
+ + "\"";
+ }
+
+ /**
+ * Creates the style of the table bubble (wrapping the message table).
+ *
+ * @return the style of the table bubble
+ */
+ public static String createTableBubbleStyle()
+ {
+ return "style=\""
+ + "width:100%;"
+ + " position:relative;"
+ + "\"";
+ }
+
+ /**
+ * Creates the style of the message table bubble.
+ *
+ * @return the style of the message table bubble
+ */
+ public static String createTableBubbleMessageStyle()
+ {
+ return "style=\""
+ + "font-size:10px;"
+ + " background-image: url('"+INCOMING_MESSAGE_IMAGE_PATH+"');"
+ + " background-repeat: repeat-y;"
+ + " background-position: top left;"
+ + "\"";
+ }
+
+ /**
+ * Creates the style of the table buuble bottom left corner.
+ *
+ * @return the style of the table buuble bottom left corner
+ */
+ public static String createTableBubbleBlStyle()
+ {
+ return "style=\""
+ + "height:10px;"
+ + " background-image: url('"+INCOMING_MESSAGE_CURVES_PATH+"');"
+ + " background-repeat: no-repeat;"
+ + " background-position: 0px -20px;"
+ + "\"";
+ }
+
+ /**
+ * Creates the style of the table buuble bottom right corner.
+ *
+ * @return the style of the table buuble bottom right corner
+ */
+ public static String createTableBubbleBrStyle()
+ {
+ return "style=\""
+ + "width:8px;"
+ + " height:10px;"
+ + " background-image: url('"+INCOMING_MESSAGE_CURVES_PATH+"');"
+ + " background-repeat: no-repeat;"
+ + " background-position: -2999px -20px;"
+ + "\"";
+ }
+
+ /**
+ * Creates the style of the table buuble top left corner.
+ *
+ * @return the style of the table buuble top left corner
+ */
+ public static String createTableBubbleTlStyle()
+ {
+ return "style=\""
+ + "height:23px;"
+ + " background-image: url('"
+ +INCOMING_MESSAGE_CURVES_TOP_PATH+"');"
+ + " background-repeat: no-repeat;"
+ + " background-position: top left;"
+ + "\"";
+ }
+
+ /**
+ * Creates the style of the table buuble top right corner.
+ *
+ * @return the style of the table buuble top right corner
+ */
+ public static String createTableBubbleTrStyle()
+ {
+ return "style=\""
+ + "width:6px;"
+ + " height:23px;"
+ + " background-image: url('"
+ +INCOMING_MESSAGE_CURVES_TOP_PATH+"');"
+ + " background-repeat: no-repeat;"
+ + " background-position: -2999px 0px;"
+ + "\"";
+ }
+
+ /**
+ * Creates the style of the indicator pointing to the avatar image.
+ *
+ * @return the style of the indicator pointing to the avatar image
+ */
+ public static String createIndicatorStyle()
+ {
+ return "style =\""
+ + "width:9px;"
+ + " height:19px;"
+ + " background-image: url('"
+ + INCOMING_MESSAGE_INDICATOR_PATH+"');"
+ + " background-repeat: no-repeat;"
+ + " background-position: top right;"
+ + "\"";
+ }
+
+ /**
+ * Creates the style of the avatar image.
+ *
+ * @return the style of the avatar image
+ */
+ public static String createAvatarStyle()
+ {
+ return "style=\"width:26px;"
+ + " height:26px;"
+ + " float:left;\"";
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/OutgoingMessageStyle.java b/src/net/java/sip/communicator/impl/gui/main/chat/OutgoingMessageStyle.java
new file mode 100644
index 0000000..b64f287
--- /dev/null
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/OutgoingMessageStyle.java
@@ -0,0 +1,206 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.impl.gui.main.chat;
+
+import net.java.sip.communicator.impl.gui.*;
+
+/**
+ * Defines the CSS style of an outgoing chat message elements.
+ *
+ * @author Yana Stamcheva
+ */
+public class OutgoingMessageStyle
+ extends IncomingMessageStyle
+{
+ /**
+ * The outgoing message background image path.
+ */
+ private final static String OUTGOING_MESSAGE_IMAGE_PATH
+ = GuiActivator.getResources().getImageURL(
+ "service.gui.lookandfeel.OUTGOING_MESSAGE_BACKGROUND").toString();
+
+ /**
+ * The outgoing message right image path.
+ */
+ private final static String OUTGOING_MESSAGE_IMAGE_RIGHT_PATH
+ = GuiActivator.getResources().getImageURL(
+ "service.gui.lookandfeel.OUTGOING_MESSAGE_BACKGROUND_RIGHT")
+ .toString();
+
+ /**
+ * The outgoing message indicator image path.
+ */
+ private final static String OUTGOING_MESSAGE_INDICATOR_PATH
+ = GuiActivator.getResources().getImageURL(
+ "service.gui.lookandfeel.OUTGOING_MESSAGE_INDICATOR").toString();
+
+ /**
+ * The outgoing message round border image path.
+ */
+ private final static String OUTGOING_MESSAGE_CURVES_PATH
+ = GuiActivator.getResources().getImageURL(
+ "service.gui.lookandfeel.OUTGOING_MESSAGE_CURVES").toString();
+
+ /**
+ * The outgoing message top image path.
+ */
+ private final static String OUTGOING_MESSAGE_CURVES_TOP_PATH
+ = GuiActivator.getResources().getImageURL(
+ "service.gui.lookandfeel.OUTGOING_MESSAGE_CURVES_TOP").toString();
+
+ /**
+ * Creates the style of the table bubble (wrapping the message table).
+ *
+ * @return the style of the table bubble
+ */
+ public static String createTableBubbleStyle()
+ {
+ return "style=\""
+ + "width:100%;"
+ + " position:relative;"
+ + "\"";
+ }
+
+ /**
+ * Creates the style of the table bubble right element.
+ *
+ * @return the style of the table bubble right element
+ */
+ public static String createTableBubbleMessageRightStyle()
+ {
+ return "style=\""
+ + "width:6px;"
+ + " background-image: url('"
+ + OUTGOING_MESSAGE_IMAGE_RIGHT_PATH+"');"
+ + " background-repeat: repeat-y;"
+ + " background-position: top left;"
+ + "\"";
+ }
+
+ /**
+ * Creates the style of the message table bubble.
+ *
+ * @return the style of the message table bubble
+ */
+ public static String createTableBubbleMessageStyle()
+ {
+ return "style=\""
+ + "font-size:10px;"
+ + " background-image: url('"+OUTGOING_MESSAGE_IMAGE_PATH+"');"
+ + " background-repeat: repeat-y;"
+ + " background-position: top left;"
+ + "\"";
+ }
+
+ /**
+ * Creates the style of the table buuble bottom left corner.
+ *
+ * @return the style of the table buuble bottom left corner
+ */
+ public static String createTableBubbleBlStyle()
+ {
+ return "style=\""
+ + "height:10px;"
+ + " background-image: url('"+OUTGOING_MESSAGE_CURVES_PATH+"');"
+ + " background-repeat: no-repeat;"
+ + " background-position: 0px -20px;"
+ + "\"";
+ }
+
+ /**
+ * Creates the style of the table buuble bottom right corner.
+ *
+ * @return the style of the table buuble bottom right corner
+ */
+ public static String createTableBubbleBrStyle()
+ {
+ return "style=\""
+ + "width:6px;"
+ + " height:10px;"
+ + " background-image: url('"+OUTGOING_MESSAGE_CURVES_PATH+"');"
+ + " background-repeat: no-repeat;"
+ + " background-position: -2999px -20px;"
+ + "\"";
+ }
+
+ /**
+ * Creates the style of the table buuble top left corner.
+ *
+ * @return the style of the table buuble top left corner
+ */
+ public static String createTableBubbleTlStyle()
+ {
+ return "style=\""
+ + "height:23px;"
+ + " background-image: url('"
+ +OUTGOING_MESSAGE_CURVES_TOP_PATH+"');"
+ + " background-repeat: no-repeat;"
+ + " background-position: top left;"
+ + "\"";
+ }
+
+ /**
+ * Creates the style of the table buuble top right corner.
+ *
+ * @return the style of the table buuble top right corner
+ */
+ public static String createTableBubbleTrStyle()
+ {
+ return "style=\""
+ + "width:6px;"
+ + " height:23px;"
+ + " background-image: url('"
+ +OUTGOING_MESSAGE_CURVES_TOP_PATH+"');"
+ + " background-repeat: no-repeat;"
+ + " background-position: -2999px 0px;"
+ + "\"";
+ }
+
+ /**
+ * Creates the style of the indicator pointing to the avatar image.
+ *
+ * @return the style of the indicator pointing to the avatar image
+ */
+ public static String createIndicatorStyle()
+ {
+ return "style =\""
+ + "width:9px;"
+ + " height:19px;"
+ + " background-image: url('"
+ +OUTGOING_MESSAGE_INDICATOR_PATH+"');"
+ + " background-repeat: no-repeat;"
+ + " background-position: top left;"
+ + "\"";
+ }
+
+ /**
+ * Creates the style of the avatar image.
+ *
+ * @return the style of the avatar image
+ */
+ public static String createAvatarStyle()
+ {
+ return "style=\"width:26px;"
+ + " height:26px;"
+ + " float:right;\"";
+ }
+
+ /**
+ * Creates the style of the date.
+ *
+ * @return the style of the date
+ */
+ public static String createDateStyle()
+ {
+ return "style =\""
+ + "color:#6a6868;"
+ + " font-size:10px;"
+ + " padding-top:4px;"
+ + " text-align:right;"
+ + "\"";
+ }
+}
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/history/HistoryWindow.java b/src/net/java/sip/communicator/impl/gui/main/chat/history/HistoryWindow.java
index 2c2b216..78dd4f7 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/history/HistoryWindow.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/history/HistoryWindow.java
@@ -263,13 +263,14 @@ public class HistoryWindow
Object o = i.next();
ChatMessage chatMessage = null;
+ ProtocolProviderService protocolProvider = null;
if(o instanceof MessageDeliveredEvent)
{
MessageDeliveredEvent evt = (MessageDeliveredEvent) o;
- ProtocolProviderService protocolProvider = evt
- .getDestinationContact().getProtocolProvider();
+ protocolProvider
+ = evt.getDestinationContact().getProtocolProvider();
chatMessage = new ChatMessage(
GuiActivator.getUIService().getMainFrame()
@@ -288,6 +289,9 @@ public class HistoryWindow
{
MessageReceivedEvent evt = (MessageReceivedEvent) o;
+ protocolProvider
+ = evt.getSourceContact().getProtocolProvider();
+
chatMessage = new ChatMessage(
evt.getSourceContact().getAddress(),
evt.getSourceContact().getDisplayName(),
@@ -304,6 +308,9 @@ public class HistoryWindow
ChatRoomMessageReceivedEvent evt
= (ChatRoomMessageReceivedEvent) o;
+ protocolProvider
+ = evt.getSourceChatRoom().getParentProvider();
+
chatMessage = new ChatMessage(
evt.getSourceChatRoomMember().getName(),
evt.getTimestamp(), Chat.INCOMING_MESSAGE,
@@ -315,6 +322,9 @@ public class HistoryWindow
ChatRoomMessageDeliveredEvent evt
= (ChatRoomMessageDeliveredEvent) o;
+ protocolProvider
+ = evt.getSourceChatRoom().getParentProvider();
+
chatMessage = new ChatMessage(
evt.getSourceChatRoom().getParentProvider()
.getAccountID().getUserID(),
@@ -326,6 +336,9 @@ public class HistoryWindow
{
FileRecord fileRecord = (FileRecord) o;
+ protocolProvider
+ = fileRecord.getContact().getProtocolProvider();
+
FileHistoryConversationComponent component
= new FileHistoryConversationComponent(
this, fileRecord);
@@ -336,10 +349,13 @@ public class HistoryWindow
if (chatMessage != null)
{
processedMessage = chatConvPanel.processMessage(
- chatMessage, searchKeyword);
+ chatMessage,
+ searchKeyword,
+ protocolProvider,
+ chatMessage.getContactName());
chatConvPanel.appendMessageToEnd(processedMessage,
- ChatConversationPanel.TEXT_CONTENT_TYPE);
+ ChatHtmlUtils.TEXT_CONTENT_TYPE);
}
}
}
@@ -875,7 +891,9 @@ public class HistoryWindow
messageContentType);
String processedMessage = chatConvPanel.processMessage(
- chatMessage, searchKeyword);
+ chatMessage, searchKeyword,
+ contact.getProtocolProvider(),
+ contact.getAddress());
this.appendMessageToDocument(document, processedMessage);
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/menus/ChatRightButtonMenu.java b/src/net/java/sip/communicator/impl/gui/main/chat/menus/ChatRightButtonMenu.java
index c619a34..9393909 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/menus/ChatRightButtonMenu.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/menus/ChatRightButtonMenu.java
@@ -36,14 +36,6 @@ public class ChatRightButtonMenu
GuiActivator.getResources().getI18NString("service.gui.COPY"),
new ImageIcon(ImageLoader.getImage(ImageLoader.COPY_ICON)));
- private JMenuItem saveMenuItem = new JMenuItem(
- GuiActivator.getResources().getI18NString("service.gui.SAVE"),
- new ImageIcon(ImageLoader.getImage(ImageLoader.SAVE_ICON)));
-
- private JMenuItem printMenuItem = new JMenuItem(
- GuiActivator.getResources().getI18NString("service.gui.PRINT"),
- new ImageIcon(ImageLoader.getImage(ImageLoader.PRINT_ICON)));
-
private JMenuItem closeMenuItem = new JMenuItem(
GuiActivator.getResources().getI18NString("service.gui.CLOSE"),
new ImageIcon(ImageLoader.getImage(ImageLoader.CLOSE_ICON)));
@@ -71,47 +63,23 @@ public class ChatRightButtonMenu
this.addSeparator();
- this.add(saveMenuItem);
- this.add(printMenuItem);
-
- this.addSeparator();
-
this.add(closeMenuItem);
this.copyMenuItem.setName("copy");
- this.saveMenuItem.setName("save");
- this.printMenuItem.setName("print");
this.closeMenuItem.setName("service.gui.CLOSE");
this.copyMenuItem.addActionListener(this);
- this.saveMenuItem.addActionListener(this);
- this.printMenuItem.addActionListener(this);
this.closeMenuItem.addActionListener(this);
this.copyMenuItem.setMnemonic(
GuiActivator.getResources().getI18nMnemonic("service.gui.COPY"));
- this.saveMenuItem.setMnemonic(
- GuiActivator.getResources().getI18nMnemonic("service.gui.SAVE"));
- this.printMenuItem.setMnemonic(
- GuiActivator.getResources().getI18nMnemonic("service.gui.PRINT"));
+
this.closeMenuItem.setMnemonic(
GuiActivator.getResources().getI18nMnemonic("service.gui.CLOSE"));
this.copyMenuItem.setAccelerator(
KeyStroke.getKeyStroke(KeyEvent.VK_C,
KeyEvent.CTRL_MASK));
-
- this.saveMenuItem.setAccelerator(
- KeyStroke.getKeyStroke(KeyEvent.VK_S,
- KeyEvent.CTRL_MASK));
-
- this.printMenuItem.setAccelerator(
- KeyStroke.getKeyStroke(KeyEvent.VK_R,
- KeyEvent.CTRL_MASK));
-
- // Disable all menu items that do nothing.
- this.saveMenuItem.setEnabled(false);
- this.printMenuItem.setEnabled(false);
}
/**
@@ -168,12 +136,6 @@ public class ChatRightButtonMenu
copyMenuItem.setIcon(new ImageIcon(
ImageLoader.getImage(ImageLoader.COPY_ICON)));
- saveMenuItem.setIcon(new ImageIcon(
- ImageLoader.getImage(ImageLoader.SAVE_ICON)));
-
- printMenuItem.setIcon(new ImageIcon(
- ImageLoader.getImage(ImageLoader.PRINT_ICON)));
-
closeMenuItem.setIcon(new ImageIcon(
ImageLoader.getImage(ImageLoader.CLOSE_ICON)));
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/menus/FileMenu.java b/src/net/java/sip/communicator/impl/gui/main/chat/menus/FileMenu.java
index df0a7f5..f188fc0 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/menus/FileMenu.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/menus/FileMenu.java
@@ -20,7 +20,7 @@ import net.java.sip.communicator.util.swing.*;
/**
* The <tt>FileMenu</tt> is the menu in the chat window menu bar that contains
- * save, print and close.
+ * my chat rooms, history and close.
*
* @author Yana Stamcheva
* @author Adam Netocny
diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/toolBars/MainToolBar.java b/src/net/java/sip/communicator/impl/gui/main/chat/toolBars/MainToolBar.java
index 14faa61..1c63daf 100644
--- a/src/net/java/sip/communicator/impl/gui/main/chat/toolBars/MainToolBar.java
+++ b/src/net/java/sip/communicator/impl/gui/main/chat/toolBars/MainToolBar.java
@@ -21,7 +21,6 @@ import net.java.sip.communicator.impl.gui.main.chat.*;
import net.java.sip.communicator.impl.gui.main.chat.conference.*;
import net.java.sip.communicator.impl.gui.main.chat.history.*;
import net.java.sip.communicator.impl.gui.main.configforms.*;
-import net.java.sip.communicator.impl.gui.main.contactlist.*;
import net.java.sip.communicator.impl.gui.utils.*;
import net.java.sip.communicator.service.contactlist.*;
import net.java.sip.communicator.service.gui.*;
@@ -29,10 +28,8 @@ import net.java.sip.communicator.service.gui.Container;
import net.java.sip.communicator.service.protocol.*;
import net.java.sip.communicator.service.protocol.ServerStoredDetails.FaxDetail;
import net.java.sip.communicator.service.protocol.ServerStoredDetails.GenericDetail;
-import net.java.sip.communicator.service.protocol.ServerStoredDetails.MobilePhoneDetail;
import net.java.sip.communicator.service.protocol.ServerStoredDetails.PagerDetail;
import net.java.sip.communicator.service.protocol.ServerStoredDetails.PhoneNumberDetail;
-import net.java.sip.communicator.service.protocol.ServerStoredDetails.WorkPhoneDetail;
import net.java.sip.communicator.util.skin.*;
import net.java.sip.communicator.util.swing.*;
@@ -109,6 +106,13 @@ public class MainToolBar
ImageLoader.getImage(ImageLoader.CHAT_CALL));
/**
+ * The call button.
+ */
+ private final ChatToolbarButton callVideoButton
+ = new ChatToolbarButton(
+ ImageLoader.getImage(ImageLoader.CHAT_VIDEO_CALL));
+
+ /**
* The options button.
*/
private final ChatToolbarButton optionsButton
@@ -181,6 +185,7 @@ public class MainToolBar
this.add(leaveChatRoomButton);
this.add(callButton);
+// this.add(callVideoButton);
this.add(desktopSharingButton);
this.add(sendFileButton);
@@ -235,6 +240,11 @@ public class MainToolBar
GuiActivator.getResources().getI18NString(
"service.gui.CALL_CONTACT"));
+ this.callVideoButton.setName("callVideo");
+ this.callVideoButton.setToolTipText(
+ GuiActivator.getResources().getI18NString(
+ "service.gui.CALL_CONTACT"));
+
this.desktopSharingButton.setName("desktop");
this.desktopSharingButton.setToolTipText(
GuiActivator.getResources().getI18NString(
@@ -264,6 +274,7 @@ public class MainToolBar
inviteButton.addActionListener(this);
leaveChatRoomButton.addActionListener(this);
callButton.addActionListener(this);
+ callVideoButton.addActionListener(this);
desktopSharingButton.addActionListener(this);
historyButton.addActionListener(this);
optionsButton.addActionListener(this);
@@ -377,7 +388,7 @@ public class MainToolBar
}
}
}
-
+
callButton.setEnabled(hasTelephony || hasPhone);
desktopSharingButton.setEnabled(!getOperationSetForCapabilities(
chatPanel.chatSession.getTransportsForOperationSet(
@@ -550,84 +561,13 @@ public class MainToolBar
List<ChatTransport> contactOpSetSupported =
getOperationSetForCapabilities(telTransports,
OperationSetBasicTelephony.class);
-
+
MetaContact metaContact
= GuiActivator.getUIService().getChatContact(chatPanel);
- Iterator<Contact> contacts = metaContact.getContacts();
- List<UIContactDetail> phones = new ArrayList<UIContactDetail>();
-
- while(contacts.hasNext())
- {
- Contact contact = contacts.next();
-
- OperationSetServerStoredContactInfo infoOpSet =
- contact.getProtocolProvider().getOperationSet(
- OperationSetServerStoredContactInfo.class);
- Iterator<GenericDetail> details = null;
-
- if(infoOpSet != null)
- {
- details = infoOpSet.getAllDetailsForContact(contact);
+
+ List<UIContactDetail> phones
+ = CallManager.getAdditionalNumbers(metaContact);
- while(details.hasNext())
- {
- GenericDetail d = details.next();
- if(d instanceof PhoneNumberDetail &&
- !(d instanceof PagerDetail) &&
- !(d instanceof FaxDetail))
- {
- PhoneNumberDetail pnd = (PhoneNumberDetail)d;
- if(pnd.getNumber() != null &&
- pnd.getNumber().length() > 0)
- {
- String localizedType = null;
-
- if(d instanceof WorkPhoneDetail)
- {
- localizedType =
- GuiActivator.getResources().
- getI18NString(
- "service.gui.WORK_PHONE");
- }
- else if(d instanceof MobilePhoneDetail)
- {
- localizedType =
- GuiActivator.getResources().
- getI18NString(
- "service.gui.MOBILE_PHONE");
- }
- else
- {
- localizedType =
- GuiActivator.getResources().
- getI18NString(
- "service.gui.PHONE");
- }
-
- UIContactDetail cd =
- new UIContactDetailImpl(
- pnd.getNumber(),
- pnd.getNumber() +
- " (" + localizedType + ")",
- null,
- new ArrayList<String>(),
- null,
- null,
- null,
- pnd)
- {
- public PresenceStatus getPresenceStatus()
- {
- return null;
- }
- };
- phones.add(cd);
- }
- }
- }
- }
- }
-
if (telTransports != null || phones.size() > 0)
{
if (contactOpSetSupported.size() == 1 && phones.size() == 0)
@@ -638,7 +578,7 @@ public class MainToolBar
transport.getName());
}
else if (contactOpSetSupported.size() == 0
- && phones.size() == 1)
+ && phones.size() == 1)
{
UIContactDetail detail = phones.get(0);
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListCellRenderer.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListCellRenderer.java
index 09ad46f..d856041 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListCellRenderer.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListCellRenderer.java
@@ -61,13 +61,13 @@ public class ContactListCellRenderer
* The icon indicating an open group.
*/
private ImageIcon openedGroupIcon =
- new ImageIcon(ImageLoader.getImage(ImageLoader.DOWN_ARROW_ICON));
+ new ImageIcon(ImageLoader.getImage(ImageLoader.OPENED_GROUP_ICON));
/**
* The icon indicating a closed group.
*/
private ImageIcon closedGroupIcon =
- new ImageIcon(ImageLoader.getImage(ImageLoader.RIGHT_ARROW_ICON));
+ new ImageIcon(ImageLoader.getImage(ImageLoader.CLOSED_GROUP_ICON));
/**
* The foreground color for groups.
@@ -494,7 +494,7 @@ public class ContactListCellRenderer
= new ImageIcon(ImageLoader.getImage(ImageLoader.DOWN_ARROW_ICON));
closedGroupIcon
- = new ImageIcon(ImageLoader.getImage(ImageLoader.RIGHT_ARROW_ICON));
+ = new ImageIcon(ImageLoader.getImage(ImageLoader.CLOSED_GROUP_ICON));
int groupForegroundProperty = GuiActivator.getResources()
.getColor("service.gui.CONTACT_LIST_GROUP_FOREGROUND");
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java
index b6a5f75..ad6b3da 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/ContactListTreeCellRenderer.java
@@ -16,6 +16,8 @@ import javax.swing.*;
import javax.swing.JPopupMenu.Separator;
import javax.swing.tree.*;
+import org.jitsi.util.*;
+
import net.java.sip.communicator.impl.gui.*;
import net.java.sip.communicator.impl.gui.main.call.*;
import net.java.sip.communicator.impl.gui.main.contactlist.contactsource.*;
@@ -74,6 +76,16 @@ public class ContactListTreeCellRenderer
private static final int EXTENDED_AVATAR_WIDTH = 45;
/**
+ * The default width of the button.
+ */
+ private static final int BUTTON_WIDTH = 26;
+
+ /**
+ * The default height of the button.
+ */
+ private static final int BUTTON_HEIGHT = 27;
+
+ /**
* Left border value.
*/
private static final int LEFT_BORDER = 5;
@@ -84,14 +96,30 @@ public class ContactListTreeCellRenderer
private static final int TOP_BORDER = 2;
/**
- * Status label right border.
+ * Bottom border value.
+ */
+ private static final int BOTTOM_BORDER = 2;
+
+ /**
+ * Right border value.
*/
- private static final int STATUS_RIGHT_BORDER = 2;
+ private static final int RIGHT_BORDER = 2;
/**
- * Status label top border.
+ * The horizontal gap between columns in pixels;
*/
- private static final int STATUS_TOP_BORDER = 2;
+ private static final int H_GAP = 2;
+
+ /**
+ * The vertical gap between rows in pixels;
+ */
+ private static final int V_GAP = 3;
+
+ /**
+ * The separator image for the button toolbar.
+ */
+ private static final Image BUTTON_SEPARATOR_IMG
+ = ImageLoader.getImage(ImageLoader.CONTACT_LIST_BUTTON_SEPARATOR);
/**
* The icon used for opened groups.
@@ -131,18 +159,12 @@ public class ContactListTreeCellRenderer
/**
* The call video button.
*/
- private final SIPCommButton callVideoButton = new SIPCommButton(
- ImageLoader.getImage(ImageLoader.CALL_VIDEO_BUTTON_SMALL),
- ImageLoader.getImage(ImageLoader.CALL_VIDEO_BUTTON_SMALL_PRESSED),
- null);
+ private final SIPCommButton callVideoButton = new SIPCommButton();
/**
* The desktop sharing button.
*/
- private final SIPCommButton desktopSharingButton = new SIPCommButton(
- ImageLoader.getImage(ImageLoader.DESKTOP_BUTTON_SMALL),
- ImageLoader.getImage(ImageLoader.DESKTOP_BUTTON_SMALL_PRESSED),
- null);
+ private final SIPCommButton desktopSharingButton = new SIPCommButton();
/**
* The chat button.
@@ -152,10 +174,7 @@ public class ContactListTreeCellRenderer
/**
* The add contact button.
*/
- private final SIPCommButton addContactButton = new SIPCommButton(
- ImageLoader.getImage(ImageLoader.ADD_CONTACT_BUTTON_SMALL),
- ImageLoader.getImage(ImageLoader.ADD_CONTACT_BUTTON_SMALL_PRESSED),
- null);
+ private final SIPCommButton addContactButton = new SIPCommButton();
/**
* The constraints used to align components in the <tt>centerPanel</tt>.
@@ -209,6 +228,11 @@ public class ContactListTreeCellRenderer
private List<JButton> customActionButtons;
/**
+ * The last added button.
+ */
+ private SIPCommButton lastAddedButton;
+
+ /**
* Initializes the panel containing the node.
*/
public ContactListTreeCellRenderer()
@@ -222,11 +246,11 @@ public class ContactListTreeCellRenderer
* correctly calculated problems may occur when clicking buttons!
*/
this.setBorder(BorderFactory
- .createEmptyBorder(TOP_BORDER, LEFT_BORDER, 2, 2));
+ .createEmptyBorder( TOP_BORDER,
+ LEFT_BORDER,
+ BOTTOM_BORDER,
+ RIGHT_BORDER));
- statusLabel.setBorder(
- BorderFactory.createEmptyBorder(STATUS_TOP_BORDER,
- 0, 0, STATUS_RIGHT_BORDER));
loadSkin();
this.setOpaque(true);
@@ -237,6 +261,10 @@ public class ContactListTreeCellRenderer
this.rightLabel.setHorizontalAlignment(JLabel.RIGHT);
+ // !! IMPORTANT: General insets used for all components if not
+ // overwritten!
+ constraints.insets = new Insets(0, 0, V_GAP, H_GAP);
+
constraints.anchor = GridBagConstraints.WEST;
constraints.fill = GridBagConstraints.NONE;
constraints.gridx = 0;
@@ -595,11 +623,11 @@ public class ContactListTreeCellRenderer
if (preferredHeight > 0)
preferredSize.height = preferredHeight;
else if (contact instanceof ShowMoreContact)
- preferredSize.height = 18;
+ preferredSize.height = 20;
else if (isSelected && treeContactList.isContactButtonsVisible())
preferredSize.height = 70;
else
- preferredSize.height = 30;
+ preferredSize.height = 35;
}
else if (treeNode instanceof GroupNode)
{
@@ -611,7 +639,7 @@ public class ContactListTreeCellRenderer
if (preferredHeight > 0)
preferredSize.height = preferredHeight;
else
- preferredSize.height = 18;
+ preferredSize.height = 20;
}
return preferredSize;
@@ -639,8 +667,6 @@ public class ContactListTreeCellRenderer
constraints.gridwidth = nameLabelGridWidth;
this.add(nameLabel, constraints);
- rightLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 2));
-
constraints.anchor = GridBagConstraints.NORTHEAST;
constraints.fill = GridBagConstraints.VERTICAL;
constraints.gridx = nameLabelGridWidth + 1;
@@ -719,15 +745,6 @@ public class ContactListTreeCellRenderer
if (!isSelected)
return;
- int statusMessageLabelHeight = 0;
- if (displayDetailsLabel.getText().length() > 0)
- statusMessageLabelHeight = 20;
- else
- statusMessageLabelHeight = 15;
-
- int y = TOP_BORDER + STATUS_TOP_BORDER
- + nameLabel.getHeight() + statusMessageLabelHeight;
-
UIContactDetail imContact = null;
// For now we support instance messaging only for contacts in our
// contact list until it's implemented for external source contacts.
@@ -736,9 +753,8 @@ public class ContactListTreeCellRenderer
OperationSetBasicInstantMessaging.class);
int x = (statusIcon == null ? 0 : statusIcon.getIconWidth())
- + (statusLabel == null ? 0 : statusLabel.getIconTextGap())
+ LEFT_BORDER
- + STATUS_RIGHT_BORDER;
+ + H_GAP;
// Re-initialize the x grid.
constraints.gridx = 0;
@@ -746,20 +762,7 @@ public class ContactListTreeCellRenderer
if (imContact != null)
{
- constraints.anchor = GridBagConstraints.WEST;
- constraints.fill = GridBagConstraints.NONE;
- constraints.gridx = ++gridX;
- constraints.gridy = 2;
- constraints.gridwidth = 1;
- constraints.gridheight = 1;
- constraints.weightx = 0f;
- constraints.weighty = 0f;
- this.chatButton.setBorder(null);
- this.add(chatButton, constraints);
-
- chatButton.setBounds(x, y, 28, 28);
-
- x += chatButton.getWidth();
+ x += addButton(chatButton, ++gridX, x, false);
}
UIContactDetail telephonyContact
@@ -833,22 +836,7 @@ public class ContactListTreeCellRenderer
|| uiContact.getDescriptor() instanceof SourceContact ||
(hasPhone && providers.size() > 0))
{
- constraints.anchor = GridBagConstraints.WEST;
- constraints.fill = GridBagConstraints.NONE;
- constraints.gridx = ++gridX;
- constraints.gridy = 2;
- constraints.gridwidth = 1;
- constraints.gridheight = 1;
- constraints.weightx = 0f;
- constraints.weighty = 0f;
- this.callButton.setBorder(null);
- this.add(callButton, constraints);
-
- callButton.setBounds(x, y, 28, 28);
-
- callButton.setEnabled(telephonyContact != null || hasPhone);
-
- x += callButton.getWidth();
+ x += addButton(callButton, ++gridX, x, false);
}
UIContactDetail videoContact
@@ -864,20 +852,7 @@ public class ContactListTreeCellRenderer
null,
null).size() > 0))
{
- constraints.anchor = GridBagConstraints.WEST;
- constraints.fill = GridBagConstraints.NONE;
- constraints.gridx = ++gridX;
- constraints.gridy = 2;
- constraints.gridwidth = 1;
- constraints.gridheight = 1;
- constraints.weightx = 0f;
- constraints.weighty = 0f;
- this.callVideoButton.setBorder(null);
- this.add(callVideoButton, constraints);
-
- callVideoButton.setBounds(x, y, 28, 28);
-
- x += callVideoButton.getWidth();
+ x += addButton(callVideoButton, ++gridX, x, false);
}
UIContactDetail desktopContact
@@ -893,39 +868,13 @@ public class ContactListTreeCellRenderer
null,
null).size() > 0))
{
- constraints.anchor = GridBagConstraints.WEST;
- constraints.fill = GridBagConstraints.NONE;
- constraints.gridx = ++gridX;
- constraints.gridy = 2;
- constraints.gridwidth = 1;
- constraints.gridheight = 1;
- constraints.weightx = 0f;
- constraints.weighty = 0f;
- this.desktopSharingButton.setBorder(null);
- this.add(desktopSharingButton, constraints);
-
- desktopSharingButton.setBounds(x, y, 28, 28);
-
- x += desktopSharingButton.getWidth();
+ x += addButton(desktopSharingButton, ++gridX, x, false);
}
if (uiContact.getDescriptor() instanceof SourceContact
&& !ConfigurationManager.isAddContactDisabled())
{
- constraints.anchor = GridBagConstraints.WEST;
- constraints.fill = GridBagConstraints.NONE;
- constraints.gridx = ++gridX;
- constraints.gridy = 2;
- constraints.gridwidth = 1;
- constraints.gridheight = 1;
- constraints.weightx = 0f;
- constraints.weighty = 0f;
- this.addContactButton.setBorder(null);
- this.add(addContactButton, constraints);
-
- addContactButton.setBounds(x, y, 28, 28);
-
- x += addContactButton.getWidth();
+ x += addButton(addContactButton, ++gridX, x, false);
}
// The list of the contact actions
@@ -933,16 +882,20 @@ public class ContactListTreeCellRenderer
Collection<SIPCommButton> contactActions
= uiContact.getContactCustomActionButtons();
- if (contactActions != null)
+ if (contactActions != null && contactActions.size() > 0)
{
- initContactActionButtons(contactActions, gridX, x);
+ initContactActionButtons(contactActions, ++gridX, x);
}
else
{
addLabels(gridX);
}
- this.setBounds(0, 0, treeContactList.getWidth(), getPreferredSize().height);
+ if (lastAddedButton != null)
+ setButtonBg(lastAddedButton, gridX, true);
+
+ this.setBounds(0, 0, treeContactList.getWidth(),
+ getPreferredSize().height);
}
/**
@@ -970,28 +923,8 @@ public class ContactListTreeCellRenderer
customActionButtons.add(actionButton);
- constraints.anchor = GridBagConstraints.WEST;
- constraints.fill = GridBagConstraints.NONE;
- constraints.gridx = ++gridX;
- constraints.gridy = 2;
- constraints.gridwidth = 1;
- constraints.gridheight = 1;
- constraints.weightx = 0f;
- constraints.weighty = 0f;
- actionButton.setBorder(null);
- this.add(actionButton, constraints);
-
- int statusMessageLabelHeight = 0;
- if (displayDetailsLabel.getText().length() > 0)
- statusMessageLabelHeight = 20;
- else
- statusMessageLabelHeight = 15;
-
- actionButton.setBounds(xBounds,
- nameLabel.getHeight() + statusMessageLabelHeight
- + TOP_BORDER + STATUS_TOP_BORDER, 28, 28);
-
- xBounds += actionButton.getWidth();
+ xBounds
+ += addButton(actionButton, ++gridX, xBounds, false);
}
}
@@ -1039,6 +972,15 @@ public class ContactListTreeCellRenderer
* Returns the call button contained in the current cell.
* @return the call button contained in the current cell
*/
+ public JButton getChatButton()
+ {
+ return chatButton;
+ }
+
+ /**
+ * Returns the call button contained in the current cell.
+ * @return the call button contained in the current cell
+ */
public JButton getCallButton()
{
return callButton;
@@ -1365,7 +1307,9 @@ public class ContactListTreeCellRenderer
else if (desktopContacts.size() > 1)
{
chooseAccountDialog
- = new ChooseCallAccountPopupMenu(treeContactList, desktopContacts,
+ = new ChooseCallAccountPopupMenu(
+ treeContactList,
+ desktopContacts,
OperationSetDesktopSharingServer.class);
}
@@ -1378,7 +1322,8 @@ public class ContactListTreeCellRenderer
SwingUtilities.convertPointToScreen(location, treeContactList);
location.y = location.y
- + treeContactList.getPathBounds(treeContactList.getSelectionPath()).y;
+ + treeContactList.getPathBounds(
+ treeContactList.getSelectionPath()).y;
chooseAccountDialog.showPopupMenu(location.x + 8, location.y - 8);
}
@@ -1487,14 +1432,14 @@ public class ContactListTreeCellRenderer
tree.getWidth() - imageWidth, 0, imageWidth, imageHeight);
}
- statusLabel.setBounds( 0, 0,
+ dragC.statusLabel.setBounds( 0, 0,
statusLabel.getWidth(),
statusLabel.getHeight());
- nameLabel.setBounds(statusLabel.getWidth(), 0,
+ dragC.nameLabel.setBounds(statusLabel.getWidth(), 0,
tree.getWidth() - imageWidth - 5, nameLabel.getHeight());
- displayDetailsLabel.setBounds(
+ dragC.displayDetailsLabel.setBounds(
displayDetailsLabel.getX(),
nameLabel.getHeight(),
displayDetailsLabel.getWidth(),
@@ -1509,20 +1454,24 @@ public class ContactListTreeCellRenderer
public void loadSkin()
{
openedGroupIcon
- = new ImageIcon(ImageLoader.getImage(ImageLoader.DOWN_ARROW_ICON));
+ = new ImageIcon(ImageLoader.getImage(ImageLoader.OPENED_GROUP_ICON));
closedGroupIcon
- = new ImageIcon(ImageLoader.getImage(ImageLoader.RIGHT_ARROW_ICON));
+ = new ImageIcon(ImageLoader.getImage(ImageLoader.CLOSED_GROUP_ICON));
- callButton.setBackgroundImage(ImageLoader.getImage(
+ callButton.setIconImage(ImageLoader.getImage(
ImageLoader.CALL_BUTTON_SMALL));
+ callButton.setRolloverImage(ImageLoader.getImage(
+ ImageLoader.CALL_BUTTON_SMALL_PRESSED));
callButton.setPressedImage(ImageLoader.getImage(
ImageLoader.CALL_BUTTON_SMALL_PRESSED));
- chatButton.setBackgroundImage(ImageLoader.getImage(
+ chatButton.setIconImage(ImageLoader.getImage(
ImageLoader.CHAT_BUTTON_SMALL));
chatButton.setPressedImage(ImageLoader.getImage(
ImageLoader.CHAT_BUTTON_SMALL_PRESSED));
+ chatButton.setRolloverImage(ImageLoader.getImage(
+ ImageLoader.CHAT_BUTTON_SMALL_PRESSED));
msgReceivedImage
= ImageLoader.getImage(ImageLoader.MESSAGE_RECEIVED_ICON);
@@ -1539,17 +1488,40 @@ public class ContactListTreeCellRenderer
if (contactForegroundProperty > -1)
contactForegroundColor = new Color(contactForegroundProperty);
- callVideoButton.setBackgroundImage(ImageLoader.getImage(
+ callVideoButton.setIconImage(ImageLoader.getImage(
ImageLoader.CALL_VIDEO_BUTTON_SMALL));
-
+ callVideoButton.setRolloverImage(ImageLoader.getImage(
+ ImageLoader.CALL_VIDEO_BUTTON_SMALL_PRESSED));
callVideoButton.setPressedImage(ImageLoader.getImage(
ImageLoader.CALL_VIDEO_BUTTON_SMALL_PRESSED));
- desktopSharingButton.setBackgroundImage(ImageLoader.getImage(
+ desktopSharingButton.setIconImage(ImageLoader.getImage(
ImageLoader.DESKTOP_BUTTON_SMALL));
-
+ desktopSharingButton.setRolloverImage(ImageLoader.getImage(
+ ImageLoader.DESKTOP_BUTTON_SMALL_PRESSED));
desktopSharingButton.setPressedImage(ImageLoader.getImage(
ImageLoader.DESKTOP_BUTTON_SMALL_PRESSED));
+
+ callVideoButton.setIconImage(
+ ImageLoader.getImage(ImageLoader.CALL_VIDEO_BUTTON_SMALL));
+ callVideoButton.setRolloverImage(
+ ImageLoader.getImage(ImageLoader.CALL_VIDEO_BUTTON_SMALL_PRESSED));
+ callVideoButton.setPressedImage(
+ ImageLoader.getImage(ImageLoader.CALL_VIDEO_BUTTON_SMALL_PRESSED));
+
+ desktopSharingButton.setIconImage(
+ ImageLoader.getImage(ImageLoader.DESKTOP_BUTTON_SMALL));
+ desktopSharingButton.setRolloverImage(
+ ImageLoader.getImage(ImageLoader.DESKTOP_BUTTON_SMALL_PRESSED));
+ desktopSharingButton.setPressedImage(
+ ImageLoader.getImage(ImageLoader.DESKTOP_BUTTON_SMALL_PRESSED));
+
+ addContactButton.setIconImage(
+ ImageLoader.getImage(ImageLoader.ADD_CONTACT_BUTTON_SMALL));
+ addContactButton.setRolloverImage(
+ ImageLoader.getImage(ImageLoader.ADD_CONTACT_BUTTON_SMALL_PRESSED));
+ addContactButton.setPressedImage(
+ ImageLoader.getImage(ImageLoader.ADD_CONTACT_BUTTON_SMALL_PRESSED));
}
/**
@@ -1628,4 +1600,78 @@ public class ContactListTreeCellRenderer
}
}
}
+
+ private int addButton( SIPCommButton button,
+ int gridX,
+ int xBounds,
+ boolean isLast)
+ {
+ lastAddedButton = button;
+
+ constraints.insets = new Insets(0, 0, V_GAP, 0);
+ constraints.anchor = GridBagConstraints.WEST;
+ constraints.fill = GridBagConstraints.NONE;
+ constraints.gridx = gridX;
+ constraints.gridy = 2;
+ constraints.gridwidth = 1;
+ constraints.gridheight = 1;
+ constraints.weightx = 0f;
+ constraints.weighty = 0f;
+ this.add(button, constraints);
+
+// addButtonSeparator(gridX);
+
+ int yBounds = TOP_BORDER + BOTTOM_BORDER + 2*V_GAP
+ + GuiUtils.getStringSize(
+ nameLabel, nameLabel.getText()).height
+ + GuiUtils.getStringSize(
+ displayDetailsLabel, displayDetailsLabel.getText()).height;
+
+ button.setBounds(xBounds, yBounds, BUTTON_WIDTH, BUTTON_HEIGHT);
+
+ button.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 0));
+
+ setButtonBg(button, gridX, isLast);
+
+ return button.getWidth();// + BUTTON_SEPARATOR_IMG.getWidth(this);
+ }
+
+ private void setButtonBg(SIPCommButton button,
+ int gridX,
+ boolean isLast)
+ {
+ if (!isLast)
+ {
+ if (gridX == 1)
+ button.setBackgroundImage(ImageLoader.getImage(
+ ImageLoader.CONTACT_LIST_BUTTON_BG_LEFT));
+ else if (gridX > 1)
+ button.setBackgroundImage(ImageLoader.getImage(
+ ImageLoader.CONTACT_LIST_BUTTON_BG_MIDDLE));
+ }
+ else
+ {
+ if (gridX == 1) // We have only one button shown.
+ button.setBackgroundImage(ImageLoader.getImage(
+ ImageLoader.CONTACT_LIST_ONE_BUTTON_BG));
+ else // We set the background of the last button in the toolbar
+ button.setBackgroundImage(ImageLoader.getImage(
+ ImageLoader.CONTACT_LIST_BUTTON_BG_RIGHT));
+ }
+ }
+
+ private void addButtonSeparator(int buttonGridX)
+ {
+ JLabel separatorLabel = new JLabel(new ImageIcon(BUTTON_SEPARATOR_IMG));
+
+ constraints.anchor = GridBagConstraints.WEST;
+ constraints.fill = GridBagConstraints.NONE;
+ constraints.gridx = ++buttonGridX;
+ constraints.gridy = 2;
+ constraints.gridwidth = 1;
+ constraints.gridheight = 1;
+ constraints.weightx = 0f;
+ constraints.weighty = 0f;
+ this.add(separatorLabel, constraints);
+ }
}
diff --git a/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java b/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java
index f703aaa..37d8c9a 100644
--- a/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java
+++ b/src/net/java/sip/communicator/impl/gui/main/contactlist/TreeContactList.java
@@ -1224,25 +1224,25 @@ public class TreeContactList
/**
* Forwards the given mouse <tt>event</tt> to the list of original
* <tt>MouseListener</tt>-s.
- * @param event the <tt>MouseEvent</tt> that notified us
+ * @param e the <tt>MouseEvent</tt> that notified us
*/
- public void mouseEntered(MouseEvent event)
+ public void mouseEntered(MouseEvent e)
{
// forward the event to the original listeners
for (MouseListener listener : originalMouseListeners)
- listener.mouseEntered(event);
+ listener.mouseEntered(e);
}
/**
* Forwards the given mouse <tt>event</tt> to the list of original
* <tt>MouseListener</tt>-s.
- * @param event the <tt>MouseEvent</tt> that notified us
+ * @param e the <tt>MouseEvent</tt> that notified us
*/
- public void mouseExited(MouseEvent event)
+ public void mouseExited(MouseEvent e)
{
// forward the event to the original listeners
for (MouseListener listener : originalMouseListeners)
- listener.mouseExited(event);
+ listener.mouseExited(e);
}
/**
@@ -1278,7 +1278,14 @@ public class TreeContactList
rightButtonMenu.setVisible(true);
}
- public void mouseMoved(MouseEvent e) {}
+ public void mouseMoved(MouseEvent e)
+ {
+ dispatchEventToButtons(e);
+
+ // forward the event to the original listeners
+ for (MouseListener listener : originalMouseListeners)
+ listener.mouseReleased(e);
+ }
public void mouseDragged(MouseEvent e) {}
@@ -1335,18 +1342,29 @@ public class TreeContactList
TreePath mousePath
= this.getPathForLocation(event.getX(), event.getY());
+ ContactListTreeCellRenderer renderer
+ = (ContactListTreeCellRenderer) getCellRenderer()
+ .getTreeCellRendererComponent( this,
+ mousePath.getLastPathComponent(),
+ true,
+ true,
+ true,
+ this.getRowForPath(mousePath),
+ true);
+
// If this is not the selection path we have nothing to do here.
if (mousePath == null || !mousePath.equals(this.getSelectionPath()))
- return;
+ {
+ renderer.getChatButton().getModel().setRollover(false);
+ renderer.getCallButton().getModel().setRollover(false);
+ renderer.getCallVideoButton().getModel().setRollover(false);
+ renderer.getDesktopSharingButton().getModel().setRollover(false);
+ renderer.getAddContactButton().getModel().setRollover(false);
- JPanel renderer = (JPanel) getCellRenderer()
- .getTreeCellRendererComponent( this,
- mousePath.getLastPathComponent(),
- true,
- true,
- true,
- this.getRowForPath(mousePath),
- true);
+ this.repaint();
+
+ return;
+ }
// We need to translate coordinates here.
Rectangle r = this.getPathBounds(mousePath);
@@ -1373,10 +1391,37 @@ public class TreeContactList
5, // we're in the button for sure
event.getClickCount(),
event.isPopupTrigger());
- mouseComponent.dispatchEvent(evt);
- this.repaint();
+ ((SIPCommButton) mouseComponent).getModel()
+ .setRollover(event.getID() == MouseEvent.MOUSE_MOVED);
+
+ if (!mouseComponent.equals(renderer.getChatButton()))
+ renderer.getChatButton().getModel().setRollover(false);
+
+ if (!mouseComponent.equals(renderer.getCallButton()))
+ renderer.getCallButton().getModel().setRollover(false);
+
+ if (!mouseComponent.equals(renderer.getCallVideoButton()))
+ renderer.getCallVideoButton().getModel().setRollover(false);
+
+ if (!mouseComponent.equals(renderer.getDesktopSharingButton()))
+ renderer.getDesktopSharingButton().getModel().setRollover(false);
+
+ if (!mouseComponent.equals(renderer.getAddContactButton()))
+ renderer.getAddContactButton().getModel().setRollover(false);
+
+ mouseComponent.dispatchEvent(evt);
}
+ else
+ {
+ renderer.getChatButton().getModel().setRollover(false);
+ renderer.getCallButton().getModel().setRollover(false);
+ renderer.getCallVideoButton().getModel().setRollover(false);
+ renderer.getDesktopSharingButton().getModel().setRollover(false);
+ renderer.getAddContactButton().getModel().setRollover(false);
+ }
+
+ this.repaint();
}
/**
diff --git a/src/net/java/sip/communicator/impl/gui/main/presence/AccountStatusPanel.java b/src/net/java/sip/communicator/impl/gui/main/presence/AccountStatusPanel.java
index a49d02a..4aa50c8 100644
--- a/src/net/java/sip/communicator/impl/gui/main/presence/AccountStatusPanel.java
+++ b/src/net/java/sip/communicator/impl/gui/main/presence/AccountStatusPanel.java
@@ -345,7 +345,7 @@ public class AccountStatusPanel
*/
public void registrationStateChanged(RegistrationStateChangeEvent evt)
{
- ProtocolProviderService protocolProvider = evt.getProvider();
+ final ProtocolProviderService protocolProvider = evt.getProvider();
this.updateStatus(protocolProvider);
@@ -379,16 +379,30 @@ public class AccountStatusPanel
{
if (currentImage == null)
{
- byte[] accountImage
- = AccountInfoUtils.getImage(accountInfoOpSet);
+ currentImage
+ = AvatarCacheUtils
+ .getCachedAvatar(protocolProvider);
- // do not set empty images
- if ((accountImage != null)
- && (accountImage.length > 0))
+ if (currentImage == null)
{
- currentImage = accountImage;
- accountImageLabel.setImageIcon(currentImage);
+ byte[] accountImage
+ = AccountInfoUtils
+ .getImage(accountInfoOpSet);
+
+ // do not set empty images
+ if ((accountImage != null)
+ && (accountImage.length > 0))
+ {
+ currentImage = accountImage;
+
+ AvatarCacheUtils.cacheAvatar(
+ protocolProvider, accountImage);
+
+ accountImageLabel.setImageIcon(currentImage);
+ }
}
+ else
+ accountImageLabel.setImageIcon(currentImage);
}
if(!StringUtils.isNullOrEmpty(globalDisplayName))
@@ -570,6 +584,10 @@ public class AccountStatusPanel
currentImage = ImageUtils.toByteArray(
ImageLoader.getImage(ImageLoader.DEFAULT_USER_PHOTO));
}
+
+ AvatarCacheUtils.cacheAvatar(
+ event.getSourceProvider(), currentImage);
+
accountImageLabel.setImageIcon(currentImage);
}
diff --git a/src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java b/src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java
index e589bd4..63c21f7 100644
--- a/src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java
+++ b/src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java
@@ -196,12 +196,6 @@ public class ImageLoader
= new ImageID("service.gui.buttons.MORE_BUTTON");
/**
- * Closed group icon.
- */
- public static final ImageID RIGHT_ARROW_ICON
- = new ImageID("service.gui.icons.RIGHT_ARROW_ICON");
-
- /**
* The background of the main window and chat window.
*/
public static final ImageID DOWN_ARROW_ICON
@@ -276,6 +270,40 @@ public class ImageLoader
= new ImageID("service.gui.buttons.CALL_VIDEO_BUTTON_BG");
/**
+ * The background image for a button in contact list that is shown on the
+ * left of the button toolbar.
+ */
+ public static final ImageID CONTACT_LIST_BUTTON_BG_LEFT
+ = new ImageID("service.gui.buttons.CONTACT_LIST_BUTTON_BG_LEFT");
+
+ /**
+ * The background image for a button in contact list that is shown on the
+ * right of the button toolbar.
+ */
+ public static final ImageID CONTACT_LIST_BUTTON_BG_RIGHT
+ = new ImageID("service.gui.buttons.CONTACT_LIST_BUTTON_BG_RIGHT");
+
+ /**
+ * The background image for a button in contact list that is shown in the
+ * middle of other buttons.
+ */
+ public static final ImageID CONTACT_LIST_BUTTON_BG_MIDDLE
+ = new ImageID("service.gui.buttons.CONTACT_LIST_BUTTON_BG_MIDDLE");
+
+ /**
+ * The background image for a button in contact list if there's only one
+ * button shown.
+ */
+ public static final ImageID CONTACT_LIST_ONE_BUTTON_BG
+ = new ImageID("service.gui.buttons.CONTACT_LIST_ONE_BUTTON_BG");
+
+ /**
+ * The separator image for the button toolbar in the contact list.
+ */
+ public static final ImageID CONTACT_LIST_BUTTON_SEPARATOR
+ = new ImageID("service.gui.buttons.CONTACT_LIST_BUTTON_SEPARATOR");
+
+ /**
* The call button small image.
*/
public static final ImageID CALL_BUTTON_SMALL
@@ -344,12 +372,24 @@ public class ImageLoader
= new ImageID("service.gui.buttons.CHAT_BUTTON_SMALL_WHITE");
/**
+ * The icon used to separate buttons in the call toolbar.
+ */
+ public static final ImageID CALL_TOOLBAR_SEPARATOR
+ = new ImageID("service.gui.icons.CALL_TOOLBAR_SEPARATOR");
+
+ /**
* The chat call button image.
*/
public static final ImageID CHAT_CALL
= new ImageID("service.gui.buttons.CHAT_CALL");
/**
+ * The chat video call button image.
+ */
+ public static final ImageID CHAT_VIDEO_CALL
+ = new ImageID("service.gui.buttons.CHAT_VIDEO_CALL");
+
+ /**
* The chat call button image.
*/
public static final ImageID CHAT_DESKTOP_SHARING
@@ -368,6 +408,12 @@ public class ImageLoader
= new ImageID("service.gui.buttons.CALL_HISTORY_BUTTON_PRESSED");
/**
+ * The call history button missed call notification image.
+ */
+ public static final ImageID CALL_HISTORY_BUTTON_NOTIFICATION
+ = new ImageID("service.gui.icons.CALL_HISTORY_BUTTON_NOTIFICATION");
+
+ /**
* The chat button small pressed image.
*/
public static final ImageID CHAT_BUTTON_SMALL_PRESSED
@@ -987,13 +1033,13 @@ public class ImageLoader
/**
* The image used for opened groups.
*/
- public static final ImageID OPENED_GROUP
+ public static final ImageID OPENED_GROUP_ICON
= new ImageID("service.gui.icons.OPENED_GROUP");
/**
* The image used for closed groups.
*/
- public static final ImageID CLOSED_GROUP
+ public static final ImageID CLOSED_GROUP_ICON
= new ImageID("service.gui.icons.CLOSED_GROUP");
/**
@@ -1763,6 +1809,67 @@ public class ImageLoader
badged = image;
return badged;
}
+
+ /**
+ * Returns the given protocol image with an index allowing to distinguish
+ * different accounts from the same protocol.
+ *
+ * @param bgImage the background image
+ * @param topImage the image that should be painted on the top of the
+ * background image
+ * @param x the x coordinate of the top image
+ * @param y the y coordinate of the top image
+ * @return the result merged image
+ */
+ public static Image getImage(Image bgImage, Image topImage, int x, int y)
+ {
+ BufferedImage buffImage
+ = new BufferedImage(bgImage.getWidth(null),
+ bgImage.getHeight(null),
+ BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g = (Graphics2D) buffImage.getGraphics();
+
+ AntialiasingManager.activateAntialiasing(g);
+ g.drawImage(bgImage, 0, 0, null);
+ g.drawImage(topImage, x, y, null);
+
+ return buffImage;
+ }
+
+ /**
+ * Returns the given protocol image with an index allowing to distinguish
+ * different accounts from the same protocol.
+ *
+ * @param bgImage the background image
+ * @param text the text that should be painted on the top of the
+ * background image
+ * @return the result merged image
+ */
+ public static Image getImage(Image bgImage, String text, Component c)
+ {
+ BufferedImage buffImage
+ = new BufferedImage(bgImage.getWidth(c),
+ bgImage.getHeight(c),
+ BufferedImage.TYPE_INT_ARGB);
+ Graphics2D g = (Graphics2D) buffImage.getGraphics();
+
+ AntialiasingManager.activateAntialiasing(g);
+ g.setColor(Color.WHITE);
+ g.setFont(c.getFont().deriveFont(Font.BOLD, 9));
+ g.drawImage(bgImage, 0, 0, null);
+
+ FontMetrics fontMetrics = g.getFontMetrics();
+ int fontHeight = fontMetrics.getHeight();
+ int textWidth = fontMetrics.stringWidth(text);
+
+ g.drawString(
+ text,
+ (bgImage.getWidth(null) - textWidth)/2 + 1,
+ (bgImage.getHeight(null) - fontHeight)/2 + fontHeight - 3);
+
+ return buffImage;
+ }
+
/**
* Loads an image icon from a given image path.
* @param imagePath The identifier of the image.
diff --git a/src/net/java/sip/communicator/util/AvatarCacheUtils.java b/src/net/java/sip/communicator/util/AvatarCacheUtils.java
new file mode 100644
index 0000000..37dcac1
--- /dev/null
+++ b/src/net/java/sip/communicator/util/AvatarCacheUtils.java
@@ -0,0 +1,344 @@
+/*
+ * Jitsi, the OpenSource Java VoIP and Instant Messaging client.
+ *
+ * Distributable under LGPL license.
+ * See terms of license at gnu.org.
+ */
+package net.java.sip.communicator.util;
+
+import java.io.*;
+
+import org.jitsi.service.fileaccess.*;
+
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * The <tt>AvatarCacheUtils</tt> allows to cache an avatar or to obtain the
+ * image of a cached avatar by specifying a contact or an account address.
+ *
+ * @author Yana Stamcheva
+ */
+public class AvatarCacheUtils
+{
+ /**
+ * The logger for this class.
+ */
+ private final static Logger logger
+ = Logger.getLogger(AvatarCacheUtils.class);
+
+ /**
+ * The name (i.e. not the whole path) of the directory in which the avatar
+ * files are to be cached for later reuse.
+ */
+ private final static String AVATAR_DIR = "avatarcache";
+
+ /**
+ * Characters and their replacement in created folder names
+ */
+ private final static String[][] ESCAPE_SEQUENCES = new String[][]
+ {
+ {"&", "&_amp"},
+ {"/", "&_sl"},
+ {"\\\\", "&_bs"}, // the char \
+ {":", "&_co"},
+ {"\\*", "&_as"}, // the char *
+ {"\\?", "&_qm"}, // the char ?
+ {"\"", "&_pa"}, // the char "
+ {"<", "&_lt"},
+ {">", "&_gt"},
+ {"\\|", "&_pp"} // the char |
+ };
+
+ /**
+ * Returns the bytes of the avatar image stored for the account
+ * corresponding to the given protocol provider.
+ *
+ * @param protocolProvider the <tt>ProtocolProviderService</tt>, which
+ * account avatar image we're looking for
+ * @return the bytes of the avatar image stored for the account
+ * corresponding to the given protocol provider
+ */
+ public static byte[] getCachedAvatar(
+ ProtocolProviderService protocolProvider)
+ {
+ String avatarPath = getCachedAvatarPath(protocolProvider);
+
+ byte[] cachedAvatar = getLocallyStoredAvatar(avatarPath);
+
+ /*
+ * Caching a zero-length avatar happens but such an avatar isn't
+ * very useful.
+ */
+ if ((cachedAvatar != null) && (cachedAvatar.length > 0))
+ return cachedAvatar;
+
+ return null;
+ }
+
+ /**
+ * Returns the bytes of the avatar image stored for the account
+ * corresponding to the given protocol provider.
+ *
+ * @param protocolProvider the <tt>ProtocolProviderService</tt>, which
+ * account avatar image we're looking for
+ * @return the bytes of the avatar image stored for the account
+ * corresponding to the given protocol provider
+ */
+ public static byte[] getCachedAvatar(Contact protocolContact)
+ {
+ String avatarPath = getCachedAvatarPath(protocolContact);
+
+ byte[] cachedAvatar = getLocallyStoredAvatar(avatarPath);
+
+ /*
+ * Caching a zero-length avatar happens but such an avatar isn't
+ * very useful.
+ */
+ if ((cachedAvatar != null) && (cachedAvatar.length > 0))
+ return cachedAvatar;
+
+ return null;
+ }
+
+ /**
+ * Returns the bytes of the avatar image stored for the account
+ * corresponding to the given protocol provider.
+ *
+ * @param protocolProvider the <tt>ProtocolProviderService</tt>, which
+ * account avatar image we're looking for
+ * @return the bytes of the avatar image stored for the account
+ * corresponding to the given protocol provider
+ */
+ public static String getCachedAvatarPath(
+ ProtocolProviderService protocolProvider)
+ {
+ return AVATAR_DIR
+ + File.separator
+ + escapeSpecialCharacters(
+ protocolProvider.getAccountID().getAccountUniqueID())
+ + File.separator
+ + escapeSpecialCharacters(
+ protocolProvider.getAccountID().getAccountUniqueID());
+ }
+
+ /**
+ * Returns the bytes of the avatar image stored for the account
+ * corresponding to the given protocol provider.
+ *
+ * @param protocolProvider the <tt>ProtocolProviderService</tt>, which
+ * account avatar image we're looking for
+ * @return the bytes of the avatar image stored for the account
+ * corresponding to the given protocol provider
+ */
+ public static String getCachedAvatarPath(Contact protocolContact)
+ {
+ return AVATAR_DIR
+ + File.separator
+ + escapeSpecialCharacters(
+ protocolContact
+ .getProtocolProvider()
+ .getAccountID().getAccountUniqueID())
+ + File.separator
+ + escapeSpecialCharacters(protocolContact.getAddress());
+ }
+
+ /**
+ * Returns the bytes of the avatar image stored for the account
+ * corresponding to the given protocol provider.
+ *
+ * @param protocolProvider the <tt>ProtocolProviderService</tt>, which
+ * account avatar image we're looking for
+ * @return the bytes of the avatar image stored for the account
+ * corresponding to the given protocol provider
+ */
+ public static String getCachedAvatarPath(
+ ProtocolProviderService protocolProvider,
+ String contactAddress)
+ {
+ return AVATAR_DIR
+ + File.separator
+ + escapeSpecialCharacters(
+ protocolProvider.getAccountID().getAccountUniqueID())
+ + File.separator
+ + escapeSpecialCharacters(contactAddress);
+ }
+
+ /**
+ * Returns the avatar image corresponding to the given avatar path.
+ *
+ * @param avatarPath The path to the lovally stored avatar.
+ * @return the avatar image corresponding to the given avatar path.
+ */
+ private static byte[] getLocallyStoredAvatar(String avatarPath)
+ {
+ try
+ {
+ File avatarFile
+ = UtilActivator
+ .getFileAccessService()
+ .getPrivatePersistentFile(avatarPath);
+
+ if(avatarFile.exists())
+ {
+ FileInputStream avatarInputStream
+ = new FileInputStream(avatarFile);
+ byte[] bs = null;
+
+ try
+ {
+ int available = avatarInputStream.available();
+
+ if (available > 0)
+ {
+ bs = new byte[available];
+ avatarInputStream.read(bs);
+ }
+ }
+ finally
+ {
+ avatarInputStream.close();
+ }
+ if (bs != null)
+ return bs;
+ }
+ }
+ catch (Exception ex)
+ {
+ logger.error(
+ "Could not read avatar image from file " + avatarPath,
+ ex);
+ }
+ return null;
+ }
+
+ /**
+ * Replaces the characters that we must escape used for the created
+ * filename.
+ *
+ * @param id the <tt>String</tt> which is to have its characters escaped
+ * @return a <tt>String</tt> derived from the specified <tt>id</tt> by
+ * escaping characters
+ */
+ private static String escapeSpecialCharacters(String id)
+ {
+ String resultId = id;
+
+ for (int j = 0; j < ESCAPE_SEQUENCES.length; j++)
+ {
+ resultId = resultId.
+ replaceAll(ESCAPE_SEQUENCES[j][0], ESCAPE_SEQUENCES[j][1]);
+ }
+ return resultId;
+ }
+
+ /**
+ * Stores avatar bytes in the given <tt>Contact</tt>.
+ *
+ * @param protoContact The contact in which we store the avatar.
+ * @param avatarBytes The avatar image bytes.
+ */
+ public static void cacheAvatar( Contact protoContact,
+ byte[] avatarBytes)
+ {
+ String avatarDirPath
+ = AVATAR_DIR
+ + File.separator
+ + escapeSpecialCharacters(
+ protoContact
+ .getProtocolProvider()
+ .getAccountID().getAccountUniqueID());
+ String avatarFileName
+ = escapeSpecialCharacters(protoContact.getAddress());
+
+ cacheAvatar(avatarDirPath, avatarFileName, avatarBytes);
+ }
+ /**
+ * Stores avatar bytes for the account corresponding to the given
+ * <tt>protocolProvider</tt>.
+ *
+ * @param protocolProvider the protocol provider corresponding to the
+ * account, which avatar we're storing
+ * @param avatarBytes the avatar image bytes
+ */
+ public static void cacheAvatar( ProtocolProviderService protocolProvider,
+ byte[] avatarBytes)
+ {
+ String accountUID
+ = protocolProvider.getAccountID().getAccountUniqueID();
+
+ String avatarDirPath
+ = AVATAR_DIR
+ + File.separator
+ + escapeSpecialCharacters(accountUID);
+
+ String avatarFileName = escapeSpecialCharacters(accountUID);
+
+ cacheAvatar(avatarDirPath, avatarFileName, avatarBytes);
+ }
+
+ /**
+ * Stores avatar bytes for the account corresponding to the given
+ * <tt>protocolProvider</tt>.
+ *
+ * @param avatarDirPath the directory in which the file will be stored
+ * @param avatarFileName the name of the avatar file
+ * @param avatarBytes the avatar image bytes
+ */
+ private static void cacheAvatar(String avatarDirPath,
+ String avatarFileName,
+ byte[] avatarBytes)
+ {
+ File avatarDir = null;
+ File avatarFile = null;
+ try
+ {
+ FileAccessService fileAccessService
+ = UtilActivator.getFileAccessService();
+
+ avatarDir
+ = fileAccessService.getPrivatePersistentDirectory(
+ avatarDirPath);
+ avatarFile
+ = fileAccessService.getPrivatePersistentFile(
+ avatarDirPath + File.separator + avatarFileName);
+
+ if(!avatarFile.exists())
+ {
+ if (!avatarDir.exists() && !avatarDir.mkdirs())
+ {
+ throw
+ new IOException(
+ "Failed to create directory: "
+ + avatarDir.getAbsolutePath());
+ }
+
+ if (!avatarFile.createNewFile())
+ {
+ throw
+ new IOException(
+ "Failed to create file"
+ + avatarFile.getAbsolutePath());
+ }
+ }
+
+ FileOutputStream fileOutStream = new FileOutputStream(avatarFile);
+
+ try
+ {
+ fileOutStream.write(avatarBytes);
+ fileOutStream.flush();
+ }
+ finally
+ {
+ fileOutStream.close();
+ }
+ }
+ catch (Exception ex)
+ {
+ logger.error(
+ "Failed to store avatar. dir =" + avatarDir
+ + " file=" + avatarFile,
+ ex);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/util/GuiUtils.java b/src/net/java/sip/communicator/util/GuiUtils.java
index a106bde..aad1825 100644
--- a/src/net/java/sip/communicator/util/GuiUtils.java
+++ b/src/net/java/sip/communicator/util/GuiUtils.java
@@ -59,6 +59,23 @@ public class GuiUtils
// European equivalent.
private static final Map<Character, Character> DIGIT_MAPPINGS;
+ /**
+ * Characters and their replacement in created folder names
+ */
+ private final static String[][] ESCAPE_SEQUENCES = new String[][]
+ {
+ {"&", "&_amp"},
+ {"/", "&_sl"},
+ {"\\\\", "&_bs"}, // the char \
+ {":", "&_co"},
+ {"\\*", "&_as"}, // the char *
+ {"\\?", "&_qm"}, // the char ?
+ {"\"", "&_pa"}, // the char "
+ {"<", "&_lt"},
+ {">", "&_gt"},
+ {"\\|", "&_pp"} // the char |
+ };
+
static
{
HashMap<Character, Character> digitMap
@@ -644,4 +661,24 @@ public class GuiUtils
updateComponentTreeUI0(children[i]);
}
}
+
+ /**
+ * Replaces the characters that we must escape used for the created
+ * filename.
+ *
+ * @param string the <tt>String</tt> which is to have its characters escaped
+ * @return a <tt>String</tt> derived from the specified <tt>id</tt> by
+ * escaping characters
+ */
+ public static String escapeFileNameSpecialCharacters(String string)
+ {
+ String resultId = string;
+
+ for (int j = 0; j < ESCAPE_SEQUENCES.length; j++)
+ {
+ resultId = resultId.
+ replaceAll(ESCAPE_SEQUENCES[j][0], ESCAPE_SEQUENCES[j][1]);
+ }
+ return resultId;
+ }
}
diff --git a/src/net/java/sip/communicator/util/ImageUtils.java b/src/net/java/sip/communicator/util/ImageUtils.java
index 002dcde..dd5933d 100644
--- a/src/net/java/sip/communicator/util/ImageUtils.java
+++ b/src/net/java/sip/communicator/util/ImageUtils.java
@@ -168,7 +168,7 @@ public class ImageUtils
g.setComposite(AlphaComposite.Src);
AntialiasingManager.activateAntialiasing(g);
g.setColor(Color.WHITE);
- g.fillRoundRect(0, 0, scaledImageWidth, scaledImageHeight, 15, 15);
+ g.fillRoundRect(0, 0, scaledImageWidth, scaledImageHeight, 5, 5);
// We use SrcAtop, which effectively uses the
// alpha value as a coverage value for each pixel stored in the
diff --git a/src/net/java/sip/communicator/util/UtilActivator.java b/src/net/java/sip/communicator/util/UtilActivator.java
index e4f523b..78d6c5e 100644
--- a/src/net/java/sip/communicator/util/UtilActivator.java
+++ b/src/net/java/sip/communicator/util/UtilActivator.java
@@ -18,6 +18,7 @@ import net.java.sip.communicator.service.netaddr.*;
import net.java.sip.communicator.service.resources.*;
import org.jitsi.service.configuration.*;
+import org.jitsi.service.fileaccess.*;
import org.jitsi.service.neomedia.*;
import org.jitsi.service.resources.*;
import org.osgi.framework.*;
@@ -51,6 +52,8 @@ public class UtilActivator
private static UIService uiService;
+ private static FileAccessService fileAccessService;
+
private static BundleContext bundleContext;
/**
@@ -239,6 +242,23 @@ public class UtilActivator
}
/**
+ * Returns the <tt>FileAccessService</tt> obtained from the bundle context.
+ *
+ * @return the <tt>FileAccessService</tt> obtained from the bundle context
+ */
+ public static FileAccessService getFileAccessService()
+ {
+ if (fileAccessService == null)
+ {
+ fileAccessService
+ = ServiceUtils.getService(
+ bundleContext,
+ FileAccessService.class);
+ }
+ return fileAccessService;
+ }
+
+ /**
* Returns the {@link MediaConfigurationService} instance registered in the
* <tt>BundleContext</tt> of the <tt>UtilActivator</tt>.
*
diff --git a/src/net/java/sip/communicator/util/swing/OrderedTransparentPanel.java b/src/net/java/sip/communicator/util/swing/OrderedTransparentPanel.java
index 9cc9367..ebc358e 100644
--- a/src/net/java/sip/communicator/util/swing/OrderedTransparentPanel.java
+++ b/src/net/java/sip/communicator/util/swing/OrderedTransparentPanel.java
@@ -18,7 +18,7 @@ public class OrderedTransparentPanel
extends TransparentPanel
{
private static final long serialVersionUID = 0L;
-
+
public Component add(Component comp)
{
if(comp instanceof OrderedComponent)
@@ -54,7 +54,7 @@ public class OrderedTransparentPanel
int cIx;
if(c instanceof OrderedComponent)
{
- cIx = ((OrderedComponent)c).getIndex();
+ cIx = ((OrderedComponent) c).getIndex();
if(orederIndex < cIx)
{
diff --git a/src/net/java/sip/communicator/util/swing/SIPCommButton.java b/src/net/java/sip/communicator/util/swing/SIPCommButton.java
index cbdea52..db40d4d 100755
--- a/src/net/java/sip/communicator/util/swing/SIPCommButton.java
+++ b/src/net/java/sip/communicator/util/swing/SIPCommButton.java
@@ -221,19 +221,11 @@ public class SIPCommButton
g.setColor(new Color(1.0f, 1.0f, 1.0f, visibility));
- if (this.bgImage != null)
+ if (this.bgImage == null
+ && (isContentAreaFilled() || (visibility != 0.0f)))
{
g.fillRoundRect(
- this.getWidth() / 2 - this.bgImage.getWidth(null) / 2,
- this.getHeight() / 2 - this.bgImage.getHeight(null) / 2,
- bgImage.getWidth(null),
- bgImage.getHeight(null),
- 10, 10);
- }
- else if (isContentAreaFilled() || (visibility != 0.0f))
- {
- g.fillRoundRect(
- 0, 0, this.getWidth(), this.getHeight(), 10, 10);
+ 0, 0, this.getWidth(), this.getHeight(), 8, 8);
}
}
diff --git a/src/net/java/sip/communicator/util/swing/SIPCommTextButton.java b/src/net/java/sip/communicator/util/swing/SIPCommTextButton.java
index 14b130e..eb6fe7c 100644
--- a/src/net/java/sip/communicator/util/swing/SIPCommTextButton.java
+++ b/src/net/java/sip/communicator/util/swing/SIPCommTextButton.java
@@ -92,6 +92,16 @@ public class SIPCommTextButton extends JButton
}
/**
+ * Return the background image.
+ *
+ * @return the background image of this button
+ */
+ public Image getBgImage()
+ {
+ return bgImage;
+ }
+
+ /**
* Overrides the <code>paintComponent</code> method of <tt>JButton</tt> to
* paint the button background and icon, and all additional effects of this
* configurable button.
diff --git a/src/net/java/sip/communicator/util/swing/SIPCommToggleButton.java b/src/net/java/sip/communicator/util/swing/SIPCommToggleButton.java
index 6a1ca46..a18e207 100644
--- a/src/net/java/sip/communicator/util/swing/SIPCommToggleButton.java
+++ b/src/net/java/sip/communicator/util/swing/SIPCommToggleButton.java
@@ -234,12 +234,17 @@ public class SIPCommToggleButton
}
}
+ int bgWidth = (bgImage != null)
+ ? bgImage.getWidth(null)
+ : getWidth();
+ int bgHeight = (bgImage != null)
+ ? bgImage.getHeight(null)
+ : getHeight();
+
if (iconImageFinal != null)
g.drawImage(iconImageFinal,
- (this.bgImage.getWidth(null) - iconImageFinal
- .getWidth(null)) / 2, (this.bgImage
- .getHeight(null) - iconImageFinal
- .getHeight(null)) / 2, this);
+ (bgWidth - iconImageFinal.getWidth(null)) / 2,
+ (bgHeight - iconImageFinal.getHeight(null)) / 2, this);
}
/**
diff --git a/src/net/java/sip/communicator/util/swing/SoundLevelIndicator.java b/src/net/java/sip/communicator/util/swing/SoundLevelIndicator.java
index 92b65dd..4e81bc9 100644
--- a/src/net/java/sip/communicator/util/swing/SoundLevelIndicator.java
+++ b/src/net/java/sip/communicator/util/swing/SoundLevelIndicator.java
@@ -32,11 +32,29 @@ public class SoundLevelIndicator
*/
private static final long serialVersionUID = 0L;
- private static final String SOUND_LEVEL_ACTIVE
- = "service.gui.soundlevel.SOUND_LEVEL_ACTIVE";
+ private static final String SOUND_LEVEL_ACTIVE_LEFT
+ = "service.gui.soundlevel.SOUND_LEVEL_ACTIVE_LEFT";
- private static final String SOUND_LEVEL_INACTIVE
- = "service.gui.soundlevel.SOUND_LEVEL_INACTIVE";
+ private static final String SOUND_LEVEL_ACTIVE_LEFT_GRADIENT
+ = "service.gui.soundlevel.SOUND_LEVEL_ACTIVE_LEFT_GRADIENT";
+
+ private static final String SOUND_LEVEL_ACTIVE_MIDDLE
+ = "service.gui.soundlevel.SOUND_LEVEL_ACTIVE_MIDDLE";
+
+ private static final String SOUND_LEVEL_ACTIVE_RIGHT
+ = "service.gui.soundlevel.SOUND_LEVEL_ACTIVE_RIGHT";
+
+ private static final String SOUND_LEVEL_ACTIVE_RIGHT_GRADIENT
+ = "service.gui.soundlevel.SOUND_LEVEL_ACTIVE_RIGHT_GRADIENT";
+
+ private static final String SOUND_LEVEL_INACTIVE_LEFT
+ = "service.gui.soundlevel.SOUND_LEVEL_INACTIVE_LEFT";
+
+ private static final String SOUND_LEVEL_INACTIVE_MIDDLE
+ = "service.gui.soundlevel.SOUND_LEVEL_INACTIVE_MIDDLE";
+
+ private static final String SOUND_LEVEL_INACTIVE_RIGHT
+ = "service.gui.soundlevel.SOUND_LEVEL_INACTIVE_RIGHT";
/**
* The maximum possible sound level.
@@ -62,12 +80,42 @@ public class SoundLevelIndicator
/**
* Image when a sound level block is active
*/
- private ImageIcon soundLevelActiveImage;
+ private ImageIcon soundLevelActiveImageLeft;
+
+ /**
+ * Image when a sound level block is active
+ */
+ private ImageIcon soundLevelActiveImageLeftGradient;
+
+ /**
+ * Image when a sound level block is active
+ */
+ private ImageIcon soundLevelActiveImageMiddle;
+
+ /**
+ * Image when a sound level block is active
+ */
+ private ImageIcon soundLevelActiveImageRight;
+
+ /**
+ * Image when a sound level block is active
+ */
+ private ImageIcon soundLevelActiveImageRightGradient;
+
+ /**
+ * Image when a sound level block is not active
+ */
+ private ImageIcon soundLevelInactiveImageLeft;
/**
* Image when a sound level block is not active
*/
- private ImageIcon soundLevelInactiveImage;
+ private ImageIcon soundLevelInactiveImageMiddle;
+
+ /**
+ * Image when a sound level block is not active
+ */
+ private ImageIcon soundLevelInactiveImageRight;
/**
* Initializes a new <tt>SoundLevelIndicator</tt> instance.
@@ -143,12 +191,42 @@ public class SoundLevelIndicator
if (c instanceof JLabel)
{
+ Icon activeIcon = null;
+ Icon inactiveIcon = null;
+ if (i == 0)
+ {
+ if (activeSoundBarCount == 1)
+ activeIcon = soundLevelActiveImageLeftGradient;
+ else
+ {
+ activeIcon = soundLevelActiveImageLeft;
+ inactiveIcon = soundLevelInactiveImageLeft;
+ }
+ }
+ else if (i == activeSoundBarCount - 1)
+ {
+ if (i == components.length - 1)
+ activeIcon = soundLevelActiveImageRight;
+ else
+ activeIcon = soundLevelActiveImageRightGradient;
+ }
+ else if (i == components.length - 1)
+ {
+ inactiveIcon = soundLevelInactiveImageRight;
+ }
+ else
+ {
+ activeIcon = soundLevelActiveImageMiddle;
+ inactiveIcon = soundLevelInactiveImageMiddle;
+ }
+
((JLabel) c).setIcon(
(i < activeSoundBarCount)
- ? soundLevelActiveImage
- : soundLevelInactiveImage);
+ ? activeIcon
+ : inactiveIcon);
}
}
+
repaint();
}
@@ -183,7 +261,13 @@ public class SoundLevelIndicator
}
while (soundBarCount < newSoundBarCount)
{
- JLabel soundBar = new JLabel(soundLevelInactiveImage);
+ JLabel soundBar;
+ if (soundBarCount == 0)
+ soundBar = new JLabel(soundLevelInactiveImageLeft);
+ else if (soundBarCount == newSoundBarCount - 1)
+ soundBar = new JLabel(soundLevelInactiveImageRight);
+ else
+ soundBar = new JLabel(soundLevelInactiveImageMiddle);
soundBar.setVerticalAlignment(JLabel.CENTER);
add(soundBar);
@@ -206,7 +290,7 @@ public class SoundLevelIndicator
*/
private int getSoundBarCount(int width)
{
- int soundBarWidth = soundLevelActiveImage.getIconWidth();
+ int soundBarWidth = soundLevelActiveImageLeft.getIconWidth();
return width / soundBarWidth;
}
@@ -218,28 +302,43 @@ public class SoundLevelIndicator
{
ResourceManagementService resources = UtilActivator.getResources();
- soundLevelActiveImage = resources.getImage(SOUND_LEVEL_ACTIVE);
- soundLevelInactiveImage = resources.getImage(SOUND_LEVEL_INACTIVE);
+ soundLevelActiveImageLeft
+ = resources.getImage(SOUND_LEVEL_ACTIVE_LEFT);
+ soundLevelActiveImageLeftGradient
+ = resources.getImage(SOUND_LEVEL_ACTIVE_LEFT_GRADIENT);
+ soundLevelActiveImageMiddle
+ = resources.getImage(SOUND_LEVEL_ACTIVE_MIDDLE);
+ soundLevelActiveImageRight
+ = resources.getImage(SOUND_LEVEL_ACTIVE_RIGHT);
+ soundLevelActiveImageRightGradient
+ = resources.getImage(SOUND_LEVEL_ACTIVE_RIGHT_GRADIENT);
+
+ soundLevelInactiveImageLeft
+ = resources.getImage(SOUND_LEVEL_INACTIVE_LEFT);
+ soundLevelInactiveImageMiddle
+ = resources.getImage(SOUND_LEVEL_INACTIVE_MIDDLE);
+ soundLevelInactiveImageRight
+ = resources.getImage(SOUND_LEVEL_INACTIVE_RIGHT);
if (!isPreferredSizeSet())
{
int preferredHeight = 0;
int preferredWidth = 0;
- if (soundLevelActiveImage != null)
+ if (soundLevelActiveImageLeft != null)
{
- int height = soundLevelActiveImage.getIconHeight();
- int width = soundLevelActiveImage.getIconWidth();
+ int height = soundLevelActiveImageLeft.getIconHeight();
+ int width = soundLevelActiveImageLeft.getIconWidth();
if (preferredHeight < height)
preferredHeight = height;
if (preferredWidth < width)
preferredWidth = width;
}
- if (soundLevelInactiveImage != null)
+ if (soundLevelInactiveImageLeft != null)
{
- int height = soundLevelInactiveImage.getIconHeight();
- int width = soundLevelInactiveImage.getIconWidth();
+ int height = soundLevelInactiveImageLeft.getIconHeight();
+ int width = soundLevelInactiveImageLeft.getIconWidth();
if (preferredHeight < height)
preferredHeight = height;
diff --git a/src/net/java/sip/communicator/util/swing/plaf/SIPCommTabbedPaneUI.java b/src/net/java/sip/communicator/util/swing/plaf/SIPCommTabbedPaneUI.java
index 554119b..93f7c6c 100644
--- a/src/net/java/sip/communicator/util/swing/plaf/SIPCommTabbedPaneUI.java
+++ b/src/net/java/sip/communicator/util/swing/plaf/SIPCommTabbedPaneUI.java
@@ -78,7 +78,7 @@ public class SIPCommTabbedPaneUI
public static final int BUTTONSIZE = 15;
- public static final int WIDTHDELTA = 10;
+ public static final int WIDTHDELTA = 1;
private static final Border PRESSEDBORDER = new SoftBevelBorder(
SoftBevelBorder.LOWERED);
@@ -237,9 +237,10 @@ public class SIPCommTabbedPaneUI
tabPane.putClientProperty("html", null);
- iconRect.x = tabRect.x + 5;
+ iconRect.y = iconRect.y + 2;
+ iconRect.x = tabRect.x + 7;
+ textRect.y = textRect.y + 2;
textRect.x = iconRect.x + iconRect.width + 5;
-
}
protected MouseListener createMouseListener()
@@ -649,8 +650,7 @@ public class SIPCommTabbedPaneUI
if (cropShape)
{
save = g2.getClip();
- g2
- .clipRect(tabRect.x, tabRect.y, tabRect.width,
+ g2.clipRect(tabRect.x, tabRect.y, tabRect.width,
tabRect.height);
}
@@ -687,7 +687,7 @@ public class SIPCommTabbedPaneUI
else if (isOver || isSelected)
{
int dx = tabRect.x + tabRect.width - BUTTONSIZE - WIDTHDELTA;
- int dy = (tabRect.y + tabRect.height) / 2 - 7;
+ int dy = (tabRect.y + tabRect.height) / 2 - 3;
if (isCloseButtonEnabled)
paintCloseIcon(g2, dx, dy, isOver);
diff --git a/src/net/java/sip/communicator/util/swing/plaf/SIPCommTextFieldUI.java b/src/net/java/sip/communicator/util/swing/plaf/SIPCommTextFieldUI.java
index 5b68197..1b1a643 100644
--- a/src/net/java/sip/communicator/util/swing/plaf/SIPCommTextFieldUI.java
+++ b/src/net/java/sip/communicator/util/swing/plaf/SIPCommTextFieldUI.java
@@ -183,7 +183,7 @@ public class SIPCommTextFieldUI
if(isRounded)
{
g2.fillRoundRect(1, 1, c.getWidth() - 1, c.getHeight() - 1,
- 20, 20);
+ 8, 8);
}
else
{
@@ -225,8 +225,8 @@ public class SIPCommTextFieldUI
if(isRounded)
{
- g2.drawRoundRect(0, 0, c.getWidth() - 1, c.getHeight() - 1,
- 20, 20);
+ g2.drawRoundRect(
+ 0, 0, c.getWidth() - 1, c.getHeight() - 1, 8, 8);
}
else
{
diff --git a/src/net/java/sip/communicator/util/util.manifest.mf b/src/net/java/sip/communicator/util/util.manifest.mf
index 64557f4..7e08cd4 100644
--- a/src/net/java/sip/communicator/util/util.manifest.mf
+++ b/src/net/java/sip/communicator/util/util.manifest.mf
@@ -41,6 +41,7 @@ Import-Package: com.sun.awt,
org.jitsi.service.neomedia,
org.jitsi.service.neomedia.codec,
org.jitsi.service.resources,
+ org.jitsi.service.fileaccess,
org.jitsi.util,
org.jitsi.util.event,
org.jitsi.util.swing,