diff options
author | Ingo Bauersachs <ingo@jitsi.org> | 2012-02-20 07:13:49 +0000 |
---|---|---|
committer | Ingo Bauersachs <ingo@jitsi.org> | 2012-02-20 07:13:49 +0000 |
commit | 05f451075674ea296bbc418f86737ea3358f6ac1 (patch) | |
tree | 19689857017df8334eafae853cd9289c6ed1e4da /src/net/java/sip | |
parent | 63c9ed630acba1bf5b7712f786b6b16445f87c18 (diff) | |
download | jitsi-05f451075674ea296bbc418f86737ea3358f6ac1.zip jitsi-05f451075674ea296bbc418f86737ea3358f6ac1.tar.gz jitsi-05f451075674ea296bbc418f86737ea3358f6ac1.tar.bz2 |
Make the OTR <authenticate buddy> text clickable (Patch by Daniel Perren, FHNW)
Diffstat (limited to 'src/net/java/sip')
8 files changed, 287 insertions, 18 deletions
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 1605c0d..bc18ea5 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 @@ -10,6 +10,7 @@ import java.awt.*; import java.awt.datatransfer.*; import java.awt.event.*; import java.io.*; +import java.net.*; import java.util.*; import java.util.Map.*; import java.util.regex.*; @@ -76,10 +77,18 @@ public class ChatConversationPanel "(" + "(\\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(); @@ -1072,6 +1081,8 @@ public class ChatConversationPanel /** * 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. */ @@ -1088,7 +1099,25 @@ public class ChatConversationPanel else if ((e.getModifiers() & InputEvent.BUTTON1_MASK) != 0 && currentHref != null && currentHref.length() != 0) { - GuiActivator.getBrowserLauncher().openURL(currentHref); + 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 @@ -1104,7 +1133,8 @@ public class ChatConversationPanel */ private void openContextMenu(Point p) { - if (currentHref != null && currentHref.length() != 0) + if (currentHref != null && currentHref.length() != 0 + && !currentHref.startsWith("jitsi://")) { rightButtonMenu.insert(openLinkItem, 0); rightButtonMenu.insert(copyLinkItem, 1); @@ -1432,6 +1462,28 @@ public class ChatConversationPanel } /** + * 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 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 29365cd..9458fa3 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 @@ -2604,4 +2604,24 @@ public class ChatPanel ChatConversationPanel.HTML_CONTENT_TYPE); } + + /** + * Add a new ChatLinkClickedListener + * + * @param listener ChatLinkClickedListener + */ + public void addChatLinkClickedListener(ChatLinkClickedListener listener) + { + conversationPanel.addChatLinkClickedListener(listener); + } + + /** + * Remove existing ChatLinkClickedListener + * + * @param listener ChatLinkClickedListener + */ + public void removeChatLinkClickedListener(ChatLinkClickedListener listener) + { + conversationPanel.removeChatLinkClickedListener(listener); + } }
\ No newline at end of file diff --git a/src/net/java/sip/communicator/plugin/otr/OtrActionHandlers.java b/src/net/java/sip/communicator/plugin/otr/OtrActionHandlers.java new file mode 100644 index 0000000..e4cd81f --- /dev/null +++ b/src/net/java/sip/communicator/plugin/otr/OtrActionHandlers.java @@ -0,0 +1,36 @@ +/*
+ * 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.plugin.otr;
+
+import java.awt.*;
+import net.java.sip.communicator.service.protocol.*;
+
+/**
+ * Class for storing OTR functions used by the menus, buttons, links, etc.
+ *
+ * @author Daniel Perren
+ */
+class OtrActionHandlers
+{
+ /**
+ * Opening the standard authorisation dialog for OTR fingerprints.
+ *
+ * @param contact the contact you would like to authenticate.
+ */
+ static void openAuthDialog(Contact contact)
+ {
+ // Launch auth buddy dialog.
+ OtrBuddyAuthenticationDialog authenticateBuddyDialog =
+ new OtrBuddyAuthenticationDialog(contact);
+ Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+
+ authenticateBuddyDialog.setLocation(screenSize.width / 2
+ - authenticateBuddyDialog.getWidth() / 2, screenSize.height / 2
+ - authenticateBuddyDialog.getHeight() / 2);
+ authenticateBuddyDialog.setVisible(true);
+ }
+}
\ No newline at end of file diff --git a/src/net/java/sip/communicator/plugin/otr/OtrContactMenu.java b/src/net/java/sip/communicator/plugin/otr/OtrContactMenu.java index 5b1dd2e..d960595 100644 --- a/src/net/java/sip/communicator/plugin/otr/OtrContactMenu.java +++ b/src/net/java/sip/communicator/plugin/otr/OtrContactMenu.java @@ -120,17 +120,8 @@ class OtrContactMenu OtrActivator.scOtrEngine.refreshSession(contact); else if (ACTION_COMMAND_AUTHENTICATE_BUDDY.equals(actionCommand)) - { // Launch auth buddy dialog. - OtrBuddyAuthenticationDialog authenticateBuddyDialog = - new OtrBuddyAuthenticationDialog(contact); - Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize(); - - authenticateBuddyDialog.setLocation(screenSize.width / 2 - - authenticateBuddyDialog.getWidth() / 2, screenSize.height / 2 - - authenticateBuddyDialog.getHeight() / 2); - authenticateBuddyDialog.setVisible(true); - } + OtrActionHandlers.openAuthDialog(contact); else if (ACTION_COMMAND_CB_ENABLE.equals(actionCommand)) { diff --git a/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java b/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java index f524169..f45a9d3 100644 --- a/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java +++ b/src/net/java/sip/communicator/plugin/otr/ScOtrEngineImpl.java @@ -5,6 +5,7 @@ */
package net.java.sip.communicator.plugin.otr;
+import java.net.*;
import java.security.*;
import java.util.*;
@@ -20,12 +21,13 @@ import net.java.sip.communicator.service.protocol.*; * @author George Politis
*/
public class ScOtrEngineImpl
- implements ScOtrEngine
+ implements ScOtrEngine,
+ ChatLinkClickedListener
{
private final OtrConfigurator configurator = new OtrConfigurator();
- private static final Map<SessionID, Contact> contactsMap =
- new Hashtable<SessionID, Contact>();
+ private static final Map<ScSessionID, Contact> contactsMap =
+ new Hashtable<ScSessionID, Contact>();
private final List<String> injectedMessageUIDs = new Vector<String>();
@@ -146,13 +148,30 @@ public class ScOtrEngineImpl if (!OtrActivator.scOtrKeyManager.isVerified(contact))
{
+ UUID sessionGuid = null;
+ for(ScSessionID scSessionID : contactsMap.keySet())
+ {
+ if(scSessionID.getSessionID().equals(sessionID))
+ {
+ sessionGuid = scSessionID.getGUID();
+ break;
+ }
+ }
+
+ OtrActivator.uiService.getChat(contact)
+ .addChatLinkClickedListener(ScOtrEngineImpl.this);
+
String unverifiedSessionWarning =
OtrActivator.resourceService
.getI18NString(
"plugin.otr.activator.unverifiedsessionwarning",
new String[]
- { contact.getDisplayName() });
-
+ {
+ contact.getDisplayName(),
+ this.getClass().getName(),
+ "AUTHENTIFICATION",
+ sessionGuid.toString()
+ });
OtrActivator.uiService.getChat(contact).addMessage(
contact.getDisplayName(),
System.currentTimeMillis(), Chat.SYSTEM_MESSAGE,
@@ -205,9 +224,13 @@ public class ScOtrEngineImpl .getAccountUniqueID(), contact.getAddress(), contact
.getProtocolProvider().getProtocolName());
+ if(contactsMap.containsKey(sessionID))
+ return sessionID;
+
+ ScSessionID scSessionID = new ScSessionID(sessionID);
synchronized (contactsMap)
{
- contactsMap.put(sessionID, contact);
+ contactsMap.put(scSessionID, contact);
}
return sessionID;
@@ -345,4 +368,22 @@ public class ScOtrEngineImpl for (ScOtrEngineListener l : listeners)
l.contactPolicyChanged(contact);
}
+
+ public void chatLinkClicked(URI url)
+ {
+ String action = url.getPath();
+ if(action.equals("/AUTHENTIFICATION"))
+ {
+ UUID guid = UUID.fromString(url.getQuery());
+ for(ScSessionID scSessionID : contactsMap.keySet())
+ {
+ if(scSessionID.getGUID().equals(guid))
+ {
+ Contact c = contactsMap.get(scSessionID.getSessionID());
+ OtrActionHandlers.openAuthDialog(c);
+ break;
+ }
+ }
+ }
+ }
}
diff --git a/src/net/java/sip/communicator/plugin/otr/ScSessionID.java b/src/net/java/sip/communicator/plugin/otr/ScSessionID.java new file mode 100644 index 0000000..cba4130 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/otr/ScSessionID.java @@ -0,0 +1,84 @@ +/*
+ * 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.plugin.otr;
+
+import java.util.*;
+import net.java.otr4j.session.*;
+
+/**
+ * Class used to associate a random UUID to an OTR4J SessionID.
+ *
+ * @author Daniel Perren
+ */
+
+public class ScSessionID
+{
+ private SessionID sessionID;
+ private UUID guid = UUID.randomUUID();
+
+ /**
+ * Creates a new instance of this class.
+ * @param sessionID the OTR4J SessionID that is being wrapped.
+ */
+ public ScSessionID(SessionID sessionID)
+ {
+ this.sessionID = sessionID;
+ }
+
+ /**
+ * Gets the wrapped session ID
+ *
+ * @return sessionID
+ */
+ public SessionID getSessionID()
+ {
+ return sessionID;
+ }
+
+ /**
+ * Returns {@link SessionID#hashCode()} of the wrapped SessionID.
+ * @return HashCode of the wrapped SessionID.
+ */
+ @Override
+ public int hashCode()
+ {
+ return sessionID.hashCode();
+ }
+
+ /**
+ * Get the current GUID.
+ *
+ * @return The GUID generated for this SessionID.
+ */
+ public UUID getGUID()
+ {
+ return guid;
+ }
+
+ /**
+ * Overrides equals() for the ability to get the hashcode from sessionID.
+ * @param obj the object to compare
+ * @return true if the objects are considered equal.
+ */
+ @Override
+ public boolean equals(Object obj)
+ {
+ if(obj == null)
+ return false;
+ return sessionID.toString().equals(obj.toString());
+ }
+
+ /**
+ * Returns {@link SessionID#toString()} of the wrapped SessionID.
+ * @return String representation of the wrapped SessionID.
+ */
+ @Override
+ public String toString()
+ {
+ return sessionID.toString();
+ }
+}
diff --git a/src/net/java/sip/communicator/service/gui/Chat.java b/src/net/java/sip/communicator/service/gui/Chat.java index db2b4e9..38c2d48 100644 --- a/src/net/java/sip/communicator/service/gui/Chat.java +++ b/src/net/java/sip/communicator/service/gui/Chat.java @@ -198,6 +198,27 @@ public interface Chat String message, String contentType); /** + * Adds a new ChatLinkClickedListener. The callback is called for every + * link whose scheme is <tt>jitsi</tt>. It is the callback's responsibility + * to filter the action based on the URI. + * + * Example:<br> + * <tt>jitsi://classname/action?query</tt><br> + * Use the name of the registering class as the host, the action to execute + * as the path and any parameters as the query. + * + * @param listener callback that is notified when a link was clicked. + */ + public void addChatLinkClickedListener(ChatLinkClickedListener listener); + + /** + * Removes an existing ChatLinkClickedListener + * + * @param listener the already registered listener to remove. + */ + public void removeChatLinkClickedListener(ChatLinkClickedListener listener); + + /** * Provides the {@link Highlighter} used in rendering the chat editor. * * @return highlighter used to render message being composed diff --git a/src/net/java/sip/communicator/service/gui/ChatLinkClickedListener.java b/src/net/java/sip/communicator/service/gui/ChatLinkClickedListener.java new file mode 100644 index 0000000..a102dbf --- /dev/null +++ b/src/net/java/sip/communicator/service/gui/ChatLinkClickedListener.java @@ -0,0 +1,24 @@ +/*
+ * 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.service.gui;
+
+import java.net.*;
+
+/**
+ * Event-callback for clicks on links.
+ *
+ * @author Daniel Perren
+ */
+public interface ChatLinkClickedListener
+{
+ /**
+ * Callback that is executed when a link was clicked.
+ *
+ * @param url The URI of the link that was clicked.
+ */
+ public void chatLinkClicked(URI url);
+}
|