diff --git a/resources/images/images.properties b/resources/images/images.properties index 86881b33d..b96951911 100644 --- a/resources/images/images.properties +++ b/resources/images/images.properties @@ -112,6 +112,7 @@ 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.AUTO_ANSWER_CHECK=resources/images/impl/gui/common/autoAnswerCheck.png # Status icons service.gui.statusicons.USER_ONLINE_ICON=resources/images/impl/gui/common/statusicons/online.png diff --git a/resources/images/impl/gui/common/autoAnswerCheck.png b/resources/images/impl/gui/common/autoAnswerCheck.png new file mode 100644 index 000000000..202a58a26 Binary files /dev/null and b/resources/images/impl/gui/common/autoAnswerCheck.png differ diff --git a/src/net/java/sip/communicator/impl/gui/main/menus/AutoAnswerMenu.java b/src/net/java/sip/communicator/impl/gui/main/menus/AutoAnswerMenu.java index 221ffc55d..cfcaf17b8 100644 --- a/src/net/java/sip/communicator/impl/gui/main/menus/AutoAnswerMenu.java +++ b/src/net/java/sip/communicator/impl/gui/main/menus/AutoAnswerMenu.java @@ -8,6 +8,7 @@ import java.awt.*; import java.awt.event.*; +import java.awt.image.*; import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.utils.*; @@ -80,18 +81,11 @@ public static void registerMenuItems(SIPCommMenu parentMenu) } // if we are in disabled menu mode and we have only one item - // change its name (like global autoanswer) + // change its name (like global auto answer) if( ConfigurationManager.isAutoAnswerDisableSubmenu() && getAutoAnswerItemCount(parentMenu) == 1) { - AutoAnswerMenuItem item = getAutoAnswerItem(parentMenu, 0); - if(item != null) - { - item.setText(GuiActivator.getResources().getI18NString( - "service.gui.AUTO_ANSWER")); - item.setIcon(new ImageIcon( - ImageLoader.getImage(ImageLoader.CALL_16x16_ICON))); - } + updateItem(getAutoAnswerItem(parentMenu, 0), true); } } @@ -165,31 +159,50 @@ private static void addAccount(ProtocolProviderService protocolProvider, JMenuItem item = parentMenu.getItem(i); if(item instanceof AutoAnswerMenuItem) { - item.setText( - AutoAnswerMenuItem.getItemDisplayName( - ((AutoAnswerMenuItem)item).getProtocolProvider())); - item.setIcon(new ImageIcon( - ((AutoAnswerMenuItem)item).getProtocolProvider() - .getProtocolIcon().getIcon( - ProtocolIcon.ICON_SIZE_16x16))); + updateItem((AutoAnswerMenuItem)item, false); } } } else if(initialCount == 0) { // this is the first item set its name like global one - AutoAnswerMenuItem item = getAutoAnswerItem(parentMenu, 0); - if(item != null) - { - item.setText(GuiActivator.getResources().getI18NString( - "service.gui.AUTO_ANSWER")); - item.setIcon(new ImageIcon( - ImageLoader.getImage(ImageLoader.CALL_16x16_ICON))); - } + updateItem(getAutoAnswerItem(parentMenu, 0), true); } } } + /** + * Updates item text and icon. + * @param item the item to update + * @param isGlobal whether to make a global item. + */ + private static void updateItem(AutoAnswerMenuItem item, boolean isGlobal) + { + if(item == null) + return; + + if(isGlobal) + { + item.setText(GuiActivator.getResources().getI18NString( + "service.gui.AUTO_ANSWER")); + item.setIcon(new ImageIcon( + getIconForProvider(item.getProtocolProvider(), + ImageLoader.getImage(ImageLoader.CALL_16x16_ICON), + item))); + } + else + { + item.setText( + AutoAnswerMenuItem.getItemDisplayName( + item.getProtocolProvider())); + item.setIcon(new ImageIcon( + getIconForProvider( + item.getProtocolProvider(), + null, + item))); + } + } + /** * Adds a menu item for the account given by protocolProvider. * @param protocolProvider the ProtocolProviderService, for which @@ -218,7 +231,7 @@ private static void addAccountInternal( return; AutoAnswerMenuItem providerMenu = - new AutoAnswerMenuItem(protocolProvider); + new AutoAnswerMenuItem(protocolProvider, parentMenu); int lastAutoAnswerIx = 0; boolean isMenuAdded = false; @@ -254,7 +267,7 @@ else if (protocolCompare == 0) if (accountId.getDisplayName() .compareTo(menuAccountID.getDisplayName()) < 0) { - parentMenu.insert( providerMenu, menuIndex); + parentMenu.insert(providerMenu, menuIndex); isMenuAdded = true; break; } @@ -321,14 +334,7 @@ public static void removeAccount(ProtocolProviderService protocolProvider, if(ConfigurationManager.isAutoAnswerDisableSubmenu() && getAutoAnswerItemCount(parentMenu) == 1) { - AutoAnswerMenuItem item = getAutoAnswerItem(parentMenu, 0); - if(item != null) - { - item.setText(GuiActivator.getResources().getI18NString( - "service.gui.AUTO_ANSWER")); - item.setIcon(new ImageIcon( - ImageLoader.getImage(ImageLoader.CALL_16x16_ICON))); - } + updateItem(getAutoAnswerItem(parentMenu, 0), true); } } @@ -341,6 +347,62 @@ public void loadSkin() ImageLoader.getImage(ImageLoader.CALL_16x16_ICON))); } + /** + * Check whether any auto answer option is enabled for a protocol. + * @param providerService the provider. + * @return whether any auto answer option is enabled for a protocol. + */ + private static boolean isAutoAnswerEnabled( + ProtocolProviderService providerService) + { + OperationSetBasicAutoAnswer opset = providerService + .getOperationSet(OperationSetBasicAutoAnswer.class); + OperationSetAdvancedAutoAnswer opSetAdvanced = providerService + .getOperationSet(OperationSetAdvancedAutoAnswer.class); + + if(opset == null) + return false; + + if(opSetAdvanced != null) + { + if(opSetAdvanced.isAutoAnswerConditionSet()) + { + return true; + } + + if(!StringUtils.isNullOrEmpty(opSetAdvanced.getCallForward())) + { + return true; + } + } + + return opset.isAutoAnswerWithVideoSet() + || opset.isAutoAnswerUnconditionalSet(); + } + + /** + * Returns the icon for the provider. + * @param providerService the provider + * @param customProviderImage set custom provider image + * @return the image. + */ + private static Image getIconForProvider( + ProtocolProviderService providerService, Image customProviderImage, + ImageObserver imageObserver) + { + Image left = null; + if(isAutoAnswerEnabled(providerService)) + left = ImageLoader.getImage(ImageLoader.AUTO_ANSWER_CHECK); + + if(customProviderImage == null) + customProviderImage = ImageUtils.getBytesInImage( + providerService.getProtocolIcon().getIcon( + ProtocolIcon.ICON_SIZE_16x16)); + + return ImageUtils.getComposedImage( + left, customProviderImage, imageObserver); + } + /** * Listens for new protocol providers. */ @@ -411,17 +473,23 @@ private static class AutoAnswerMenuItem */ private ProtocolProviderService providerService; + /** + * The parent menu. + */ + private final SIPCommMenu parentMenu; + /** * Init the menu item. * @param provider the provider. + * @param parentMenu the parent menu. */ - AutoAnswerMenuItem(ProtocolProviderService provider) + AutoAnswerMenuItem(ProtocolProviderService provider, + SIPCommMenu parentMenu) { this(provider, - getItemDisplayName(provider), - ImageUtils.getBytesInImage( - provider.getProtocolIcon().getIcon( - ProtocolIcon.ICON_SIZE_16x16))); + getItemDisplayName(provider), + getIconForProvider(provider, null, parentMenu), + parentMenu); } /** @@ -429,13 +497,16 @@ private static class AutoAnswerMenuItem * @param provider the provider. * @param displayName the display name of the item. * @param onlineImage the icon to display + * @param parentMenu the parent menu. */ private AutoAnswerMenuItem(ProtocolProviderService provider, String displayName, - Image onlineImage) + Image onlineImage, + SIPCommMenu parentMenu) { super(displayName, new ImageIcon(onlineImage)); this.providerService = provider; + this.parentMenu = parentMenu; this.addActionListener(this); } @@ -455,7 +526,8 @@ public ProtocolProviderService getProtocolProvider() */ public void actionPerformed(ActionEvent e) { - new AutoAnswerOptionsDialog(providerService).setVisible(true); + new AutoAnswerOptionsDialog(providerService, parentMenu) + .setVisible(true); } /** @@ -554,14 +626,22 @@ private static class AutoAnswerOptionsDialog */ private JTextField callFwdNumberField = new JTextField(); + /** + * The parent menu. + */ + private final SIPCommMenu parentMenu; + /** * Create dialog. * @param providerService provider. + * @param parentMenu the parent menu. */ - AutoAnswerOptionsDialog(ProtocolProviderService providerService) + AutoAnswerOptionsDialog(ProtocolProviderService providerService, + SIPCommMenu parentMenu) { super(false); + this.parentMenu = parentMenu; this.providerService = providerService; this.setTitle(GuiActivator.getResources() @@ -801,6 +881,24 @@ else if(callFwd.isSelected()) opset.setAutoAnswerWithVideo( answerWithVideoCheckBox.isSelected()); + + // as settings changed lets update items + if( ConfigurationManager.isAutoAnswerDisableSubmenu() + && getAutoAnswerItemCount(parentMenu) == 1) + { + updateItem(getAutoAnswerItem(parentMenu, 0), true); + } + else + { + for(int i = 0; i < parentMenu.getItemCount(); i++) + { + JMenuItem item = parentMenu.getItem(i); + if(item instanceof AutoAnswerMenuItem) + { + updateItem((AutoAnswerMenuItem)item, false); + } + } + } } dispose(); 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 fe8a52c6f..e589bd445 100644 --- a/src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java +++ b/src/net/java/sip/communicator/impl/gui/utils/ImageLoader.java @@ -1603,6 +1603,9 @@ public class ImageLoader public static final ImageID SOUND_SETTING_BUTTON_PRESSED = new ImageID("service.gui.soundlevel.SOUND_SETTING_BUTTON_PRESSED"); + public static final ImageID AUTO_ANSWER_CHECK + = new ImageID("service.gui.icons.AUTO_ANSWER_CHECK"); + /** * Loads an image from a given image identifier. * diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresenceJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresenceJabberImpl.java index 5a587b335..27b8e25f3 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresenceJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetPersistentPresenceJabberImpl.java @@ -1344,7 +1344,8 @@ public void createAccountPhotoPresenceInterceptor() } catch(XMPPException ex) { - logger.info("Can not retrieve account avatar", ex); + logger.info("Can not retrieve account avatar for " + + parentProvider.getOurJID() + ": " + ex.getMessage()); } // Creates the presence extension to generates the the element diff --git a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetServerStoredAccountInfoJabberImpl.java b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetServerStoredAccountInfoJabberImpl.java index 642e172dd..8431277ae 100644 --- a/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetServerStoredAccountInfoJabberImpl.java +++ b/src/net/java/sip/communicator/impl/protocol/jabber/OperationSetServerStoredAccountInfoJabberImpl.java @@ -12,8 +12,8 @@ import net.java.sip.communicator.service.protocol.event.*; import net.java.sip.communicator.service.protocol.ServerStoredDetails.*; +import net.java.sip.communicator.util.*; import org.jivesoftware.smack.*; -import org.jivesoftware.smackx.packet.*; /** * The Account Info Operation set is a means of accessing and modifying detailed @@ -25,6 +25,15 @@ public class OperationSetServerStoredAccountInfoJabberImpl extends AbstractOperationSetServerStoredAccountInfo { + /** + * The logger. + */ + private static final Logger logger = + Logger.getLogger(OperationSetServerStoredAccountInfoJabberImpl.class); + + /** + * The info retriever. + */ private InfoRetreiver infoRetreiver = null; /** @@ -387,7 +396,7 @@ private boolean uploadImageDetail( } catch (XMPPException xmppe) { - xmppe.printStackTrace(); + logger.error("Error loading/saving vcard: ", xmppe); } return isPhotoChanged; diff --git a/src/net/java/sip/communicator/util/ImageUtils.java b/src/net/java/sip/communicator/util/ImageUtils.java index c94616322..002dcdea1 100644 --- a/src/net/java/sip/communicator/util/ImageUtils.java +++ b/src/net/java/sip/communicator/util/ImageUtils.java @@ -390,4 +390,60 @@ public static Image getBytesInImage(byte[] imageBytes) } return image; } + + /** + * Creates a composed image from two images. If one of the images + * is missing will add an empty space on its place. + * @param leftImage the left image. + * @param rightImage the right image + * @param imageObserver need to calculate image sizes. + * @return the composed image. + */ + public static Image getComposedImage( + Image leftImage, Image rightImage, + ImageObserver imageObserver) + { + int height = 0; + if(leftImage == null && rightImage == null) + return null; + if(leftImage != null && rightImage != null) + height = Math.max(leftImage.getHeight(imageObserver), + rightImage.getHeight(imageObserver)); + else if(leftImage == null) + height = rightImage.getHeight(imageObserver); + else + height = leftImage.getHeight(imageObserver); + + int width = 0; + int leftWidth = 0; + if(leftImage != null && rightImage != null) + { + leftWidth = leftImage.getWidth(imageObserver); + width = leftWidth + + rightImage.getWidth(imageObserver); + } + else if(leftImage == null) + { + leftWidth = rightImage.getWidth(imageObserver); + width = leftWidth*2; + } + else + { + leftWidth = leftImage.getWidth(imageObserver); + width = leftWidth*2; + } + + BufferedImage buffImage = + new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB); + Graphics2D g = (Graphics2D) buffImage.getGraphics(); + + AntialiasingManager.activateAntialiasing(g); + g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER)); + if(leftImage != null) + g.drawImage(leftImage, 0, 0, null); + if(rightImage != null) + g.drawImage(rightImage, leftWidth + 1, 0, null); + + return buffImage; + } }