diff --git a/src/net/java/sip/communicator/impl/argdelegation/ArgDelegationActivator.java b/src/net/java/sip/communicator/impl/argdelegation/ArgDelegationActivator.java index 99ed0e389..3b0bc88b3 100644 --- a/src/net/java/sip/communicator/impl/argdelegation/ArgDelegationActivator.java +++ b/src/net/java/sip/communicator/impl/argdelegation/ArgDelegationActivator.java @@ -31,7 +31,7 @@ public class ArgDelegationActivator * A reference to the delegation peer implementation that is currently * handling uri arguments. */ - private UriDelegationPeerImpl delegationPeer = null; + private ArgDelegationPeerImpl delegationPeer = null; /** * A reference to the UIService currently in use in @@ -49,7 +49,7 @@ public class ArgDelegationActivator public void start(BundleContext bc) throws Exception { bundleContext = bc; - delegationPeer = new UriDelegationPeerImpl(bc); + delegationPeer = new ArgDelegationPeerImpl(bc); bc.addServiceListener(delegationPeer); //register our instance of delegation peer. diff --git a/src/net/java/sip/communicator/impl/argdelegation/UriDelegationPeerImpl.java b/src/net/java/sip/communicator/impl/argdelegation/ArgDelegationPeerImpl.java similarity index 89% rename from src/net/java/sip/communicator/impl/argdelegation/UriDelegationPeerImpl.java rename to src/net/java/sip/communicator/impl/argdelegation/ArgDelegationPeerImpl.java index 9d58951a0..ad89d1b11 100644 --- a/src/net/java/sip/communicator/impl/argdelegation/UriDelegationPeerImpl.java +++ b/src/net/java/sip/communicator/impl/argdelegation/ArgDelegationPeerImpl.java @@ -24,11 +24,11 @@ * * @author Emil Ivov */ -public class UriDelegationPeerImpl - implements UriDelegationPeer, ServiceListener +public class ArgDelegationPeerImpl + implements ArgDelegationPeer, ServiceListener { private static final Logger logger = - Logger.getLogger(UriDelegationPeerImpl.class); + Logger.getLogger(ArgDelegationPeerImpl.class); /** * The list of uriHandlers that we are currently aware of. @@ -38,12 +38,12 @@ public class UriDelegationPeerImpl /** * Creates an instance of this peer and scans bundleContext for all - * existing UriHandlers + * existing UriHandler * * @param bundleContext a reference to a currently valid instance of a * bundle context. */ - public UriDelegationPeerImpl(BundleContext bundleContext) + public ArgDelegationPeerImpl(BundleContext bundleContext) { ServiceReference[] uriHandlerRefs = null; @@ -182,5 +182,17 @@ public void handleUri(String uriArg) } } + /** + * This method would simply bring the application on focus as it is called + * when the user has tried to launch a second instance of SIP Communicator + * while a first one was already running. Future implementations may also + * show an error/information message to the user notifying them that a + * second instance is not to be launched. + */ + public void handleConcurrentInvocationRequest() + { + ArgDelegationActivator.getUIService().setVisible(true); + } + } 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 862fa9a69..38c9e9a3a 100755 --- a/src/net/java/sip/communicator/impl/gui/main/MainFrame.java +++ b/src/net/java/sip/communicator/impl/gui/main/MainFrame.java @@ -1579,6 +1579,7 @@ public void run() { MainFrame.this.addNativePlugins(); MainFrame.super.setVisible(isVisible); + MainFrame.super.setExtendedState(MainFrame.NORMAL); MainFrame.super.toFront(); } else diff --git a/src/net/java/sip/communicator/impl/systray/jdic/SystrayServiceJdicImpl.java b/src/net/java/sip/communicator/impl/systray/jdic/SystrayServiceJdicImpl.java index 672f1ca28..a58a57115 100644 --- a/src/net/java/sip/communicator/impl/systray/jdic/SystrayServiceJdicImpl.java +++ b/src/net/java/sip/communicator/impl/systray/jdic/SystrayServiceJdicImpl.java @@ -72,9 +72,9 @@ public class SystrayServiceJdicImpl private int maxMessageNumber = 3; private SystrayMessage aggregatedMessage; - + /** - * Stores the system time, when the main window was restored the last time + * Stores the system time, when the main window was restored the last time */ private long setVisibleTime = 0; @@ -95,14 +95,14 @@ public class SystrayServiceJdicImpl private ImageIcon logoIconWhite; private ImageIcon envelopeIcon; private ImageIcon envelopeIconWhite; - + /** * The dock Icons used only in Mac version */ private URL dockIconOffline; private URL dockIconAway; private URL dockIconFFC; - + private boolean initialized = false; /** @@ -153,7 +153,7 @@ private void initSystray() logoIconFFC = Resources.getImage("trayIconWindowsFFC"); envelopeIcon = Resources.getImage("messageIconWindows"); } - // If we're running under MacOSX, we use a special black and + // If we're running under MacOSX, we use a special black and // white icons without background. else if (osName.startsWith("Mac OS X")) { @@ -173,19 +173,19 @@ else if (osName.startsWith("Mac OS X")) if (!osName.startsWith("Mac OS X")) { - // default to set offline , if any protocols become + // default to set offline , if any protocols become // online will set it to online currentIcon = logoIconOffline; } else currentIcon = logoIcon; - + trayIcon = new TrayIcon(currentIcon, Resources.getApplicationString("applicationName"), menu); trayIcon.setIconAutoSize(true); - + if (osName.startsWith("Mac OS X")) { // init dock Icons @@ -208,7 +208,7 @@ public void actionPerformed(ActionEvent e) if (isVisible) { setVisibleTime = currentTime; } - else if (currentTime < (setVisibleTime + doubleClickSpeed)) + else if (currentTime < (setVisibleTime + doubleClickSpeed)) { // Do nothing. the last restore is less than 2 seconds, so it is very // likely, that the user made a double click. prevent the main window @@ -227,7 +227,7 @@ else if (currentTime < (setVisibleTime + doubleClickSpeed)) } }); - // Change the MacOSX icon with the white one when the popup + // Change the MacOSX icon with the white one when the popup // menu appears if (osName.startsWith("Mac OS X")) { @@ -243,11 +243,11 @@ public void popupMenuWillBecomeVisible(PopupMenuEvent e) else { trayIcon.setIcon(logoIconWhite); - currentIcon = logoIconWhite; + currentIcon = logoIconWhite; } } - public void popupMenuWillBecomeInvisible(PopupMenuEvent e) + public void popupMenuWillBecomeInvisible(PopupMenuEvent e) { if (currentIcon == envelopeIconWhite) { @@ -260,11 +260,11 @@ public void popupMenuWillBecomeInvisible(PopupMenuEvent e) currentIcon = logoIcon; } } - - public void popupMenuCanceled(PopupMenuEvent e) + + public void popupMenuCanceled(PopupMenuEvent e) { popupMenuWillBecomeInvisible(e); - } + } }); } @@ -297,8 +297,8 @@ public void actionPerformed(ActionEvent e) * Saves the last status for all accounts. This information is used * on logging. Each time user logs in he's logged with the same status * as he was the last time before closing the application. - * - * @param protocolProvider the protocol provider for which we save the + * + * @param protocolProvider the protocol provider for which we save the * last selected status * @param statusName the status name to save */ @@ -359,10 +359,10 @@ public void saveStatusInformation( * Implements the SystratService.showPopupMessage method. Shows * a pop up message, above the Systray icon, which has the given title, * message content and message type. - * + * * @param title the title of the message * @param messageContent the content text - * @param messageType the type of the message + * @param messageType the type of the message */ public void showPopupMessage( String title, String messageContent, @@ -370,7 +370,7 @@ public void showPopupMessage( String title, { if(!checkInitialized()) return; - + int trayMsgType = TrayIcon.NONE_MESSAGE_TYPE; if (messageType == SystrayService.ERROR_MESSAGE_TYPE) @@ -391,7 +391,7 @@ else if (messageType == SystrayService.WARNING_MESSAGE_TYPE) /** * Implements the SystrayService.addPopupMessageListener method. - * + * * @param listener the listener to add */ public void addPopupMessageListener(SystrayPopupMessageListener listener) @@ -404,7 +404,7 @@ public void addPopupMessageListener(SystrayPopupMessageListener listener) /** * Implements the SystrayService.removePopupMessageListener method. - * + * * @param listener the listener to remove */ public void removePopupMessageListener(SystrayPopupMessageListener listener) @@ -418,7 +418,7 @@ public void removePopupMessageListener(SystrayPopupMessageListener listener) /** * Notifies all interested listeners that a SystrayPopupMessageEvent * has occured. - * + * * @param sourceObject the source of this event */ private void firePopupMessageEvent(Object sourceObject) @@ -445,16 +445,16 @@ private void firePopupMessageEvent(Object sourceObject) /** * Sets a new Systray icon. - * + * * @param imageType the type of the image to set. */ public void setSystrayIcon(int imageType) { if(!checkInitialized()) return; - + String osName = System.getProperty("os.name"); - + ImageIcon toChangeSystrayIcon = null; if (imageType == SystrayService.SC_IMG_TYPE) @@ -500,13 +500,13 @@ else if (imageType == SystrayService.ENVELOPE_IMG_TYPE) toChangeSystrayIcon = envelopeIcon; } } - + if(toChangeSystrayIcon != null) { this.trayIcon.setIcon(toChangeSystrayIcon); this.currentIcon = toChangeSystrayIcon; } - + if (osName.startsWith("Mac OS X")) { URL toChangeDockIcon = null; @@ -522,7 +522,7 @@ else if (imageType == SystrayService.ENVELOPE_IMG_TYPE) case SystrayService.SC_IMG_FFC_TYPE : toChangeDockIcon = dockIconFFC; break; } - + try { if(toChangeDockIcon != null) @@ -538,7 +538,7 @@ else if (imageType == SystrayService.ENVELOPE_IMG_TYPE) } } } - + private boolean checkInitialized() { if(!initialized) @@ -549,7 +549,7 @@ private boolean checkInitialized() else return true; } - + /** * Shows the oldest message in the message queue and then removes it from * the queue. @@ -616,7 +616,7 @@ private class SystrayMessage * Creates an instance of SystrayMessage by specifying the * message title, the content of the message and the type of * the message. - * + * * @param title the title of the message * @param messageContent the content of the message * @param messageType the type of the message @@ -635,7 +635,7 @@ public SystrayMessage( String title, * message title, the content of the message, the type of * the message and the number of messages that this message has * aggregated. - * + * * @param messageContent the content of the message * @param aggregatedMessageNumber the number of messages that this * message has aggregated @@ -655,7 +655,7 @@ public SystrayMessage( String messageContent, /** * Returns the title of the message. - * + * * @return the title of the message */ public String getTitle() @@ -665,7 +665,7 @@ public String getTitle() /** * Returns the message content. - * + * * @return the message content */ public String getMessageContent() @@ -675,7 +675,7 @@ public String getMessageContent() /** * Returns the message type. - * + * * @return the message type */ public int getMessageType() @@ -685,7 +685,7 @@ public int getMessageType() /** * Returns the number of aggregated messages this message represents. - * + * * @return the number of aggregated messages this message represents. */ public int getAggregatedMessageNumber() @@ -696,7 +696,7 @@ public int getAggregatedMessageNumber() /** * Adds the given number of messages to the number of aggregated * messages contained in this message. - * + * * @param messageNumber the number of messages to add to the number of * aggregated messages contained in this message */ diff --git a/src/net/java/sip/communicator/launcher/SIPCommunicator.java b/src/net/java/sip/communicator/launcher/SIPCommunicator.java index e3d65fafc..5926aca41 100644 --- a/src/net/java/sip/communicator/launcher/SIPCommunicator.java +++ b/src/net/java/sip/communicator/launcher/SIPCommunicator.java @@ -81,10 +81,10 @@ else if (osName.startsWith("Windows")) System.exit(argHandler.getErrorCode()); } - //lock our config di so that we would only have a single instance of + //lock our config dir so that we would only have a single instance of //sip communicator, no matter how many times we start it (use mainly //for handling sip: uris after starting the application) - if ( argHandlerRes != LaunchArgHandler.ACTION_CONTINUE_MULTIINSTANCE ) + if ( argHandlerRes != LaunchArgHandler.ACTION_CONTINUE_LOCK_DISABLED ) { SipCommunicatorLock lock = new SipCommunicatorLock(); diff --git a/src/net/java/sip/communicator/util/launchutils/UriDelegationPeer.java b/src/net/java/sip/communicator/util/launchutils/ArgDelegationPeer.java similarity index 63% rename from src/net/java/sip/communicator/util/launchutils/UriDelegationPeer.java rename to src/net/java/sip/communicator/util/launchutils/ArgDelegationPeer.java index e19bc180b..7e9918744 100644 --- a/src/net/java/sip/communicator/util/launchutils/UriDelegationPeer.java +++ b/src/net/java/sip/communicator/util/launchutils/ArgDelegationPeer.java @@ -15,7 +15,7 @@ * * @author Emil Ivov */ -public interface UriDelegationPeer +public interface ArgDelegationPeer { /** * Handles uriArg in whatever way it finds fit. @@ -23,4 +23,13 @@ public interface UriDelegationPeer * @param uriArg the uri argument that this delegate has to handle. */ public void handleUri(String uriArg); + + /** + * Called when the user has tried to launch a second instance of + * SIP Communicator while a first one was already running. A typical + * implementation of this method would simply bring the application on + * focus but it may also show an error/information message to the user + * notifying them that a second instance is not to be launched. + */ + public void handleConcurrentInvocationRequest(); } diff --git a/src/net/java/sip/communicator/util/launchutils/UriArgManager.java b/src/net/java/sip/communicator/util/launchutils/ArgDelegator.java similarity index 60% rename from src/net/java/sip/communicator/util/launchutils/UriArgManager.java rename to src/net/java/sip/communicator/util/launchutils/ArgDelegator.java index 6c669fc39..931b92a85 100644 --- a/src/net/java/sip/communicator/util/launchutils/UriArgManager.java +++ b/src/net/java/sip/communicator/util/launchutils/ArgDelegator.java @@ -10,25 +10,26 @@ import net.java.sip.communicator.util.*; /** - * The UriArgManager implements an utility for handling URIs that have - * been passed as command line arguments. The class maintains a list of - * registered delegates that do the actual URI handling. The UriArgDelegator - * is previewed for use with SIP Communicator argdelegation service. It would - * therefore record all URIs until the corresponding DelegationPeer has been - * registered with the UriArgManager. + * The ArgDelegator implements an utility for handling args that have + * been passed as command line arguments but that need the OSGi environment + * and SIP Communicator to be fully loaded. The class maintains a list of + * registered delegates (ArgDelegationPeers) that do the actual arg + * handling. The ArgDelegator is previewed for use with the SIP + * Communicator argdelegation service. It would therefore record all args + * until the corresponding DelegationPeer has registered here. * * @author Emil Ivov */ -class UriArgManager +class ArgDelegator { - private static final Logger logger = Logger.getLogger(UriArgManager.class); + private static final Logger logger = Logger.getLogger(ArgDelegator.class); /** * The delegation peer that we pass arguments to. This peer is going to * get set only after Felix starts and all its services have been properly * loaded. */ - private UriDelegationPeer uriDelegationPeer = null; + private ArgDelegationPeer uriDelegationPeer = null; /** * We use this list to store arguments that we have been asked to handle @@ -64,7 +65,7 @@ protected void handleUri(String uriArg) * @param delegationPeer the delegation peer that we can use to deliver * command line URIs to. */ - public void setDelegationPeer(UriDelegationPeer delegationPeer) + public void setDelegationPeer(ArgDelegationPeer delegationPeer) { synchronized(recordedArgs) { @@ -81,4 +82,22 @@ public void setDelegationPeer(UriDelegationPeer delegationPeer) recordedArgs.clear(); } } + + /** + * Called when the user has tried to launch a second instance of + * SIP Communicator while a first one was already running. This method + * simply calls its peer method from the ArgDelegationPeer and + * does nothing if no peer is currently registered. + */ + public void handleConcurrentInvocationRequest() + { + synchronized(recordedArgs) + { + if(uriDelegationPeer != null) + { + uriDelegationPeer.handleConcurrentInvocationRequest(); + } + } + + } } diff --git a/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java b/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java index fe08c2ca6..22fbd758f 100644 --- a/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java +++ b/src/net/java/sip/communicator/util/launchutils/LaunchArgHandler.java @@ -66,7 +66,7 @@ public class LaunchArgHandler * successfully parsed and one of them indicates that the user has requested * a multi instance launch. */ - public static final int ACTION_CONTINUE_MULTIINSTANCE = 3; + public static final int ACTION_CONTINUE_LOCK_DISABLED = 3; /** * The error code returned when we couldn't parse one of the options. @@ -112,7 +112,7 @@ public class LaunchArgHandler /** * A reference to the instance of the */ - private UriArgManager uriArgManager = new UriArgManager(); + private ArgDelegator argDelegator = new ArgDelegator(); /** * The singleton instance of this handler. @@ -205,7 +205,8 @@ else if (args[i].equals("-c")) //make sure we have at least one more argument left. if( i == args.length - 1) { - System.out.println("The \"-c\" option expects a directory parameter."); + System.out.println( + "The \"-c\" option expects a directory parameter."); returnAction = ACTION_ERROR; break; } @@ -214,7 +215,7 @@ else if (args[i].equals("-c")) } else if (args[i].equals("--multiple") || args[i].equals("-m")) { - handleMultipleArg(args[i]); + returnAction = ACTION_CONTINUE_LOCK_DISABLED; continue; } //if this is the last arg and it's not an option then it's probably @@ -245,7 +246,7 @@ else if ( i == args.length - 1 private void handleUri(String uri) { logger.trace("Handling uri "+ uri); - uriArgManager.handleUri(uri); + argDelegator.handleUri(uri); } /** @@ -256,15 +257,6 @@ private void handleDebugArg(String arg) System.out.println("Option " + arg + " is not yet implemented!"); } - /** - * Instructs SIP Communicator to allow for more than a single running - * instance. - */ - private void handleMultipleArg(String arg) - { - System.out.println("Option " + arg + " is not yet implemented!"); - } - /** * Instructs SIP Communicator to allow for more than a single running * instance. @@ -397,8 +389,35 @@ public int getErrorCode() * @param delegationPeer the delegationPeer that should handle URIs * or null if we'd like to unset a previously set peer. */ - public void setDelegationPeer(UriDelegationPeer delegationPeer) + public void setDelegationPeer(ArgDelegationPeer delegationPeer) + { + this.argDelegator.setDelegationPeer(delegationPeer); + } + + /** + * Called when the user has tried to launch a second instance of + * SIP Communicator while a first one was already running. This method + * only handles arguments that need to be handled by a running instance + * of SIP Communicator assuming that simple ones such as "--version" or + * "--help" have been handled by the calling instance. + * + * @param args the args that we need to handle. + */ + public void handleConcurrentInvocationRequestArgs(String[] args) { - this.uriArgManager.setDelegationPeer(delegationPeer); + //if the arg list is empty, then we simply notify SC of the request + //so that it could do stuff like showing the contact list for example. + if(args.length == 0) + { + this.argDelegator.handleConcurrentInvocationRequest(); + } + //if we 1 or more args then we only handle the last one as the only + //interinstance arg we currently know how to handle are URIs. Change + //this if we one day implement fun stuff like inter instance command + //execution. + else if(args.length >=1) + { + this.argDelegator.handleUri(args[args.length -1]); + } } } \ No newline at end of file diff --git a/src/net/java/sip/communicator/util/launchutils/SipCommunicatorLock.java b/src/net/java/sip/communicator/util/launchutils/SipCommunicatorLock.java index 51198e0fa..a56b622e6 100644 --- a/src/net/java/sip/communicator/util/launchutils/SipCommunicatorLock.java +++ b/src/net/java/sip/communicator/util/launchutils/SipCommunicatorLock.java @@ -769,7 +769,8 @@ else if (line.startsWith(ARGUMENT)) // now let's handle what we've got String[] args = new String[argsList.size()]; - LaunchArgHandler.getInstance().handleArgs( + LaunchArgHandler.getInstance() + .handleConcurrentInvocationRequestArgs( argsList.toArray(args)); } catch (IOException exc)