diff --git a/src/net/java/sip/communicator/impl/gui/UIServiceImpl.java b/src/net/java/sip/communicator/impl/gui/UIServiceImpl.java index 58f28bb77..f0bb1e776 100644 --- a/src/net/java/sip/communicator/impl/gui/UIServiceImpl.java +++ b/src/net/java/sip/communicator/impl/gui/UIServiceImpl.java @@ -54,6 +54,7 @@ public class UIServiceImpl supportedContainers.add(UIService.CONTAINER_CONTACT_RIGHT_BUTTON_MENU); supportedContainers.add(UIService.CONTAINER_GROUP_RIGHT_BUTTON_MENU); supportedContainers.add(UIService.CONTAINER_TOOLS_MENU); + supportedContainers.add(UIService.CONTAINER_HELP_MENU); supportedContainers.add(UIService.CONTAINER_CHAT_TOOL_BAR); supportedContainers.add(UIService.CONTAINER_CALL_HISTORY); supportedContainers.add(UIService.CONTAINER_MAIN_TABBED_PANE); @@ -75,7 +76,8 @@ public class UIServiceImpl * Creates an instance of UIServiceImpl. */ public UIServiceImpl() - {} + { + } /** * Initializes all frames and panels and shows the gui. @@ -514,11 +516,10 @@ public boolean getExitOnMainWindowClose() */ public void initExportedWindows() { - AboutWindow aboutWindow = new AboutWindow(mainFrame); AddContactWizard addContactWizard = new AddContactWizard(mainFrame); - exportedWindows.put(aboutWindow.getIdentifier(), aboutWindow); - exportedWindows.put(configurationFrame.getIdentifier(), configurationFrame); + exportedWindows.put(configurationFrame.getIdentifier(), + configurationFrame); exportedWindows.put(addContactWizard.getIdentifier(), addContactWizard); } diff --git a/src/net/java/sip/communicator/impl/gui/main/chat/menus/HelpMenu.java b/src/net/java/sip/communicator/impl/gui/main/chat/menus/HelpMenu.java index 7277108b5..499681b6a 100644 --- a/src/net/java/sip/communicator/impl/gui/main/chat/menus/HelpMenu.java +++ b/src/net/java/sip/communicator/impl/gui/main/chat/menus/HelpMenu.java @@ -7,14 +7,19 @@ package net.java.sip.communicator.impl.gui.main.chat.menus; +import java.awt.Component; import java.awt.event.*; +import java.util.Iterator; import javax.swing.*; +import net.java.sip.communicator.impl.gui.GuiActivator; import net.java.sip.communicator.impl.gui.customcontrols.*; import net.java.sip.communicator.impl.gui.i18n.*; import net.java.sip.communicator.impl.gui.main.*; import net.java.sip.communicator.impl.gui.main.chat.*; +import net.java.sip.communicator.service.gui.UIService; +import net.java.sip.communicator.service.gui.event.*; import net.java.sip.communicator.util.*; /** * The HelpMenu is a menu in the main application menu bar. @@ -23,15 +28,14 @@ */ public class HelpMenu extends SIPCommMenu - implements ActionListener + implements ActionListener, + PluginComponentListener { private Logger logger = Logger.getLogger(HelpMenu.class.getName()); private I18NString aboutString = Messages.getI18NString("about"); - private JMenuItem aboutItem = new JMenuItem(aboutString.getText()); - private ChatWindow chatWindow; /** @@ -44,29 +48,60 @@ public HelpMenu(ChatWindow chatWindow) { this.chatWindow = chatWindow; - this.add(aboutItem); + this.chatWindow = chatWindow; + + this.setMnemonic(Messages.getI18NString("help").getMnemonic()); + + this.initPluginComponents(); + } - this.aboutItem.setName("about"); + /** + * Initialize plugin components already registered for this container. + */ + private void initPluginComponents() + { + Iterator pluginComponents = GuiActivator.getUIService() + .getComponentsForContainer(UIService.CONTAINER_CHAT_HELP_MENU); - this.aboutItem.addActionListener(this); + while (pluginComponents.hasNext()) + { + Component o = (Component) pluginComponents.next(); - this.aboutItem.setMnemonic(aboutString.getMnemonic()); + this.add(o); + } + + GuiActivator.getUIService().addPluginComponentListener(this); } /** - * Handles the ActionEvent when one of the menu items is selected. - * - * @param evt the ActionEvent that has just occurred. + * Handles the ActionEvent when one of the menu items is + * selected. */ - public void actionPerformed(ActionEvent evt) { + public void actionPerformed(ActionEvent e) + { + } - JMenuItem menuItem = (JMenuItem) evt.getSource(); - String itemName = menuItem.getName(); + public void pluginComponentAdded(PluginComponentEvent event) + { + Component c = (Component) event.getSource(); - if (itemName.equals("about")) { - AboutWindow aboutWindow = new AboutWindow(chatWindow); + if (event.getContainerID().equals(UIService.CONTAINER_CHAT_HELP_MENU)) + { + this.add(c); - aboutWindow.setVisible(true); + this.revalidate(); + this.repaint(); } } + + public void pluginComponentRemoved(PluginComponentEvent event) + { + Component c = (Component) event.getSource(); + + if (event.getContainerID().equals(UIService.CONTAINER_CHAT_HELP_MENU)) + { + this.remove(c); + } + } + } diff --git a/src/net/java/sip/communicator/impl/gui/main/menus/HelpMenu.java b/src/net/java/sip/communicator/impl/gui/main/menus/HelpMenu.java index a7fabe57c..4a7aaed0d 100644 --- a/src/net/java/sip/communicator/impl/gui/main/menus/HelpMenu.java +++ b/src/net/java/sip/communicator/impl/gui/main/menus/HelpMenu.java @@ -1,5 +1,4 @@ /* - * SIP Communicator, the OpenSource Java VoIP and Instant Messaging client. * * Distributable under LGPL license. * See terms of license at gnu.org. @@ -7,67 +6,96 @@ package net.java.sip.communicator.impl.gui.main.menus; +import java.awt.*; import java.awt.event.*; +import java.util.*; -import javax.swing.*; - +import net.java.sip.communicator.impl.gui.*; import net.java.sip.communicator.impl.gui.customcontrols.*; import net.java.sip.communicator.impl.gui.i18n.*; import net.java.sip.communicator.impl.gui.main.*; -import net.java.sip.communicator.util.*; +import net.java.sip.communicator.service.gui.*; +import net.java.sip.communicator.service.gui.event.*; + /** * The HelpMenu is a menu in the main application menu bar. * * @author Yana Stamcheva + * @author Thomas Hofer */ -public class HelpMenu +public class HelpMenu extends SIPCommMenu - implements ActionListener + implements ActionListener, + PluginComponentListener { - private Logger logger = Logger.getLogger(HelpMenu.class.getName()); - - private I18NString aboutString = Messages.getI18NString("about"); - - private JMenuItem aboutItem - = new JMenuItem(aboutString.getText()); - private MainFrame mainFrame; - + /** * Creates an instance of HelpMenu. - * @param mainFrame the parent window + * + * @param mainFrame + * the parent window */ - public HelpMenu (MainFrame mainFrame) + public HelpMenu(MainFrame mainFrame) { super(Messages.getI18NString("help").getText()); - + this.mainFrame = mainFrame; - - this.add(aboutItem); - - this.aboutItem.setName("about"); - - this.aboutItem.addActionListener(this); - + this.setMnemonic(Messages.getI18NString("help").getMnemonic()); - - this.aboutItem.setMnemonic(aboutString.getMnemonic()); + + this.initPluginComponents(); } /** - * Handles the ActionEvent when one of the menu items is selected. + * Initialize plugin components already registered for this container. */ - public void actionPerformed(ActionEvent e) { + private void initPluginComponents() + { + Iterator pluginComponents = GuiActivator.getUIService() + .getComponentsForContainer(UIService.CONTAINER_HELP_MENU); - JMenuItem menuItem = (JMenuItem) e.getSource(); - String itemName = menuItem.getName(); + while (pluginComponents.hasNext()) + { + Component o = (Component) pluginComponents.next(); - if (itemName.equals("about")) { - AboutWindow aboutWindow = new AboutWindow(mainFrame); - - aboutWindow.setVisible(true); + this.add(o); } + + GuiActivator.getUIService().addPluginComponentListener(this); + } + + /** + * Handles the ActionEvent when one of the menu items is + * selected. + */ + public void actionPerformed(ActionEvent e) + { } + + public void pluginComponentAdded(PluginComponentEvent event) + { + Component c = (Component) event.getSource(); + + if (event.getContainerID().equals(UIService.CONTAINER_HELP_MENU)) + { + this.add(c); + + this.revalidate(); + this.repaint(); + } + } + + public void pluginComponentRemoved(PluginComponentEvent event) + { + Component c = (Component) event.getSource(); + + if (event.getContainerID().equals(UIService.CONTAINER_HELP_MENU)) + { + this.remove(c); + } + } + } diff --git a/src/net/java/sip/communicator/impl/gui/main/AboutWindow.java b/src/net/java/sip/communicator/plugin/splashscreen/AboutWindow.java similarity index 61% rename from src/net/java/sip/communicator/impl/gui/main/AboutWindow.java rename to src/net/java/sip/communicator/plugin/splashscreen/AboutWindow.java index 86f59230d..f83b9ee7f 100644 --- a/src/net/java/sip/communicator/impl/gui/main/AboutWindow.java +++ b/src/net/java/sip/communicator/plugin/splashscreen/AboutWindow.java @@ -1,213 +1,239 @@ -package net.java.sip.communicator.impl.gui.main; - -import java.awt.*; -import java.awt.event.*; - -import javax.swing.*; -import javax.swing.event.*; - -import net.java.sip.communicator.impl.gui.*; -import net.java.sip.communicator.impl.gui.customcontrols.*; -import net.java.sip.communicator.impl.gui.i18n.*; -import net.java.sip.communicator.impl.gui.utils.*; -import net.java.sip.communicator.service.gui.*; - -public class AboutWindow - extends SIPCommDialog - implements HyperlinkListener, - ActionListener, - ExportedWindow -{ - private WindowBackground mainPanel = new WindowBackground(); - - private JLabel titleLabel = new JLabel("SIP Communicator"); - - private JLabel versionLabel = - new JLabel(" " + System.getProperty("sip-communicator.version")); - - private JTextArea logoArea = - new JTextArea("Open Source VoIP & Instant Messaging"); - - private StyledHTMLEditorPane rightsArea = new StyledHTMLEditorPane(); - - private StyledHTMLEditorPane licenseArea = new StyledHTMLEditorPane(); - - private I18NString okString = Messages.getI18NString("ok"); - - private JButton okButton = new JButton(okString.getText()); - - private JPanel buttonPanel = new JPanel(new FlowLayout(FlowLayout.RIGHT)); - - private JPanel textPanel = new JPanel(); - - public AboutWindow(Frame owner) - { - super(owner); - - this.setTitle(Messages.getI18NString("about").getText()); - this.setModal(false); - - this.mainPanel.setLayout(new BorderLayout()); - - this.textPanel.setPreferredSize(new Dimension(470, 280)); - this.textPanel.setLayout(new BoxLayout(textPanel, BoxLayout.Y_AXIS)); - this.textPanel.setBorder(BorderFactory - .createEmptyBorder(15, 15, 15, 15)); - this.textPanel.setOpaque(false); - - this.titleLabel.setFont(Constants.FONT.deriveFont(Font.BOLD, 28)); - this.titleLabel.setForeground(Constants.DARK_BLUE); - this.titleLabel.setAlignmentX(Component.RIGHT_ALIGNMENT); - - this.versionLabel.setFont(Constants.FONT.deriveFont(Font.BOLD, 18)); - this.versionLabel.setForeground(Color.GRAY); - this.versionLabel.setAlignmentX(Component.RIGHT_ALIGNMENT); - - this.logoArea.setFont(Constants.FONT.deriveFont(Font.BOLD, 14)); - this.logoArea.setForeground(Constants.DARK_BLUE); - this.logoArea.setOpaque(false); - this.logoArea.setLineWrap(true); - this.logoArea.setWrapStyleWord(true); - this.logoArea.setEditable(false); - this.logoArea.setPreferredSize(new Dimension(100, 20)); - this.logoArea.setAlignmentX(Component.RIGHT_ALIGNMENT); - this.logoArea.setBorder(BorderFactory.createEmptyBorder(30, 180, 0, 0)); - - this.rightsArea.setContentType("text/html"); - - String startDivTag = "
+ * When a paragraph in a JTextPane has a large amount of text the
+ * processing needed to layout the entire paragraph increases as the
+ * paragraph grows.
+ */
+ static class ParagraphViewX extends ParagraphView {
+ public ParagraphViewX(Element elem) {
+ super(elem);
+ }
+
+ /**
+ * Calculate equirements along the minor axis. This
+ * is implemented to forward the request to the logical
+ * view by calling getMinimumSpan, getPreferredSpan, and
+ * getMaximumSpan on it.
+ */
+ protected SizeRequirements calculateMinorAxisRequirements (
+ int axis, SizeRequirements r) {
+ if (r == null) {
+ r = new SizeRequirements();
+ }
+ float pref = layoutPool.getPreferredSpan(axis);
+ float min = layoutPool.getMinimumSpan(axis);
+ // Don't include insets, Box.getXXXSpan will include them.
+ r.minimum = (int)min;
+ r.preferred = Math.max(r.minimum, (int) pref);
+ r.maximum = Short.MAX_VALUE;
+ r.alignment = 0.5f;
+ return r;
+ }
+ }
+
+
+ /**
+ * Create an uninitialized text storage model
+ * that is appropriate for this type of editor.
+ *
+ * @return the model.
+ */
+ public Document createDefaultDocument() {
+ StyleSheet styles = getStyleSheet();
+ StyleSheet ss = new StyleSheet();
+
+ ss.addStyleSheet(styles);
+
+ HTMLDocument doc = new HTMLDocument(ss);
+ doc.setParser(getParser());
+ doc.setAsynchronousLoadPriority(4);
+ doc.setTokenThreshold(100);
+ return doc;
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/splashscreen/SIPCommImageView.java b/src/net/java/sip/communicator/plugin/splashscreen/SIPCommImageView.java
new file mode 100644
index 000000000..dbbfc3326
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/splashscreen/SIPCommImageView.java
@@ -0,0 +1,861 @@
+/*
+ * SIP Communicator, 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.splashscreen;
+
+import java.io.*;
+import java.net.*;
+import java.util.*;
+import javax.imageio.*;
+
+import java.awt.*;
+import java.awt.image.*;
+import javax.swing.*;
+import javax.swing.event.*;
+import javax.swing.text.*;
+import javax.swing.text.html.*;
+
+import net.java.sip.communicator.util.*;
+
+/*
+ * The content of this file was based on code borrowed from Rob Kenworthy,
+ * http://www.javaworld.com/javaworld/javatips/jw-javatip109.html#resources.
+ */
+/**
+ * The SIPCommImageView is an ImageView which allows to
+ * specify a related path when describing an image within an html document.
+ *
+ * @author Yana Stamcheva
+ */
+public class SIPCommImageView extends ImageView implements ImageObserver
+{
+ private Logger logger = Logger.getLogger(SIPCommImageView.class);
+
+ public static final String TOP = "top";
+
+ public static final String TEXTTOP = "texttop";
+
+ public static final String MIDDLE = "middle";
+
+ public static final String ABSMIDDLE = "absmiddle";
+
+ public static final String CENTER = "center";
+
+ public static final String BOTTOM = "bottom";
+
+ /**
+ * Creates a new view that represents an IMG element.
+ *
+ * @param elem
+ * the element to create a view for.
+ */
+ public SIPCommImageView(Element elem)
+ {
+
+ super(elem);
+
+ initialize(elem);
+
+ StyleSheet sheet = getStyleSheet();
+
+ attr = sheet.getViewAttributes(this);
+ }
+
+ /**
+ * Initializes this view.
+ *
+ * @param elem
+ * the element.
+ */
+ private void initialize(Element elem)
+ {
+ synchronized (this)
+ {
+ loading = true;
+ fWidth = fHeight = 0;
+ }
+
+ int width = 0;
+ int height = 0;
+ boolean customWidth = false;
+ boolean customHeight = false;
+
+ try
+ {
+ fElement = elem;
+
+ if (isURL())
+ {
+ URL src = getSourceURL();
+
+ if (src != null)
+ {
+
+ Dictionary cache = (Dictionary) getDocument().getProperty(
+ IMAGE_CACHE_PROPERTY);
+
+ if (cache != null)
+ fImage = (Image) cache.get(src);
+ else
+ fImage = Toolkit.getDefaultToolkit().getImage(src);
+ }
+ } else
+ {
+ /*--Code to load from relative path--*/
+ String src = (String) fElement.getAttributes().getAttribute(
+ HTML.Attribute.SRC);
+
+ if (src == null)
+ return;
+
+ // fImage = Toolkit.getDefaultToolkit().createImage(src);
+ try
+ {
+ fImage = ImageIO.read(SIPCommImageView.class
+ .getResource(src));
+
+ try
+ {
+ waitForImage();
+ } catch (InterruptedException e)
+ {
+ fImage = null;
+ }
+
+ } catch (IOException e)
+ {
+ fImage = null;
+ logger.error("Failed to read image.", e);
+ } catch (IllegalArgumentException iae)
+ {
+ fImage = null;
+ logger.error("Failed to read image.", iae);
+ }
+ }
+
+ // Get height/width from params or image or defaults:
+ height = getIntAttr(HTML.Attribute.HEIGHT, -1);
+
+ customHeight = (height > 0);
+
+ if (!customHeight && fImage != null)
+ height = fImage.getHeight(this);
+
+ if (height <= 0)
+ height = DEFAULT_HEIGHT;
+
+ width = getIntAttr(HTML.Attribute.WIDTH, -1);
+
+ customWidth = (width > 0);
+
+ if (!customWidth && fImage != null)
+ width = fImage.getWidth(this);
+
+ if (width <= 0)
+ width = DEFAULT_WIDTH;
+
+ // Make sure the image starts loading:
+ if (fImage != null)
+ if (customWidth && customHeight)
+ Toolkit.getDefaultToolkit().prepareImage(fImage, height,
+ width, this);
+ else
+ Toolkit.getDefaultToolkit().prepareImage(fImage, -1, -1,
+ this);
+ } finally
+ {
+
+ synchronized (this)
+ {
+ loading = false;
+
+ if (customWidth || fWidth == 0)
+ {
+ fWidth = width;
+ }
+ if (customHeight || fHeight == 0)
+ {
+ fHeight = height;
+ }
+ }
+ }
+ }
+
+ /**
+ * Determines if path is in the form of an URL.
+ *
+ * @return TRUE if the source is URL, FALSE otherwise.
+ */
+ private boolean isURL()
+ {
+ String src = (String) fElement.getAttributes().getAttribute(
+ HTML.Attribute.SRC);
+
+ if (src == null)
+ return false;
+
+ return src.toLowerCase().startsWith("file")
+ || src.toLowerCase().startsWith("http");
+ }
+
+ /**
+ * Make sure an image is loaded - ie no broken images. So far its used only
+ * for images loaded off the disk (non-URL).
+ *
+ * @throws InterruptedException
+ */
+ private void waitForImage() throws InterruptedException
+ {
+
+ int w = fImage.getWidth(this);
+ int h = fImage.getHeight(this);
+
+ while (true)
+ {
+ int flags = Toolkit.getDefaultToolkit().checkImage(fImage, w, h,
+ this);
+
+ if (((flags & ERROR) != 0) || ((flags & ABORT) != 0))
+ throw new InterruptedException();
+
+ else if ((flags & (ALLBITS | FRAMEBITS)) != 0)
+ return;
+
+ Thread.sleep(10);
+ }
+ }
+
+ /**
+ * Fetches the attributes to use when rendering. This is implemented to
+ * multiplex the attributes specified in the model with a StyleSheet.
+ */
+ public AttributeSet getAttributes()
+ {
+
+ return attr;
+ }
+
+ /**
+ * Checks if the image is within a link.
+ */
+ boolean isLink()
+ {
+ // ! It would be nice to cache this but in an editor it can change
+ // See if I have an HREF attribute courtesy of the enclosing A tag:
+
+ AttributeSet anchorAttr = (AttributeSet)
+
+ fElement.getAttributes().getAttribute(HTML.Tag.A);
+
+ if (anchorAttr != null)
+ {
+ return anchorAttr.isDefined(HTML.Attribute.HREF);
+ }
+ return false;
+ }
+
+ /**
+ * Returns the size of the border to use.
+ */
+ int getBorder()
+ {
+ return getIntAttr(HTML.Attribute.BORDER, isLink() ? DEFAULT_BORDER : 0);
+ }
+
+ /**
+ * Returns the amount of extra space to add along an axis.
+ */
+ int getSpace(int axis)
+ {
+ return getIntAttr(axis == X_AXIS ? HTML.Attribute.HSPACE
+ : HTML.Attribute.VSPACE, 0);
+ }
+
+ /**
+ * Returns the border's color, or null if this is not a link.
+ */
+ Color getBorderColor()
+ {
+ StyledDocument doc = (StyledDocument) getDocument();
+ return doc.getForeground(getAttributes());
+ }
+
+ /**
+ * Returns the image's vertical alignment.
+ */
+ float getVerticalAlignment()
+ {
+ String align = (String) fElement.getAttributes().getAttribute(
+ HTML.Attribute.ALIGN);
+ if (align != null)
+ {
+ align = align.toLowerCase();
+ if (align.equals(TOP) || align.equals(TEXTTOP))
+ return 0.0f;
+ else if (align.equals(this.CENTER) || align.equals(MIDDLE)
+ || align.equals(ABSMIDDLE))
+ return 0.5f;
+ }
+
+ return 1.0f; // default alignment is bottom
+ }
+
+ /**
+ * Checks if the image is at least one pixel.
+ *
+ * @param obs
+ * The ImageObserver.
+ * @return true if the image is not null and is at least one
+ * pixel big, false otherwise.
+ */
+ boolean hasPixels(ImageObserver obs)
+ {
+
+ return fImage != null && fImage.getHeight(obs) > 0
+ && fImage.getWidth(obs) > 0;
+ }
+
+ /**
+ * Returns an URL for the image source, or null if it could not be
+ * determined.
+ */
+ private URL getSourceURL()
+ {
+
+ String src = (String) fElement.getAttributes().getAttribute(
+ HTML.Attribute.SRC);
+ if (src == null)
+ return null;
+
+ URL reference = ((HTMLDocument) getDocument()).getBase();
+ try
+ {
+ URL u = new URL(reference, src);
+ return u;
+ } catch (MalformedURLException e)
+ {
+ return null;
+ }
+ }
+
+ /**
+ * Look up an integer-valued attribute. Not recursive.
+ */
+ private int getIntAttr(HTML.Attribute name, int deflt)
+ {
+ AttributeSet attr = fElement.getAttributes();
+ if (attr.isDefined(name))
+ { // does not check parents!
+ int i;
+ String val = (String) attr.getAttribute(name);
+ if (val == null)
+ i = deflt;
+ else
+ try
+ {
+ i = Math.max(0, Integer.parseInt(val));
+ } catch (NumberFormatException x)
+ {
+ i = deflt;
+ }
+ return i;
+ } else
+ return deflt;
+ }
+
+ /**
+ * Establishes the parent view for this view. Seize this moment to cache the
+ * AWT Container I'm in.
+ */
+ public void setParent(View parent)
+ {
+ super.setParent(parent);
+ fContainer = parent != null ? getContainer() : null;
+ if (parent == null && fComponent != null)
+ {
+ fComponent.getParent().remove(fComponent);
+ fComponent = null;
+ }
+ }
+
+ /**
+ * The attributes may have changed.
+ */
+ public void changedUpdate(DocumentEvent e, Shape a, ViewFactory f)
+ {
+ super.changedUpdate(e, a, f);
+ float align = getVerticalAlignment();
+
+ int height = fHeight;
+ int width = fWidth;
+
+ initialize(getElement());
+
+ boolean hChanged = fHeight != height;
+ boolean wChanged = fWidth != width;
+ if (hChanged || wChanged || getVerticalAlignment() != align)
+ {
+ getParent().preferenceChanged(this, hChanged, wChanged);
+ }
+ }
+
+ /**
+ * Paints the image.
+ *
+ * @param g
+ * the rendering surface to use
+ * @param a
+ * the allocated region to render into
+ * @see View#paint
+ */
+ public void paint(Graphics g, Shape a)
+ {
+ Color oldColor = g.getColor();
+ fBounds = a.getBounds();
+ int border = getBorder();
+ int x = fBounds.x + border + getSpace(X_AXIS);
+ int y = fBounds.y + border + getSpace(Y_AXIS);
+ int width = fWidth;
+ int height = fHeight;
+ int sel = getSelectionState();
+
+ // If no pixels yet, draw gray outline and icon:
+ if (!hasPixels(this))
+ {
+ g.setColor(Color.lightGray);
+ g.drawRect(x, y, width - 1, height - 1);
+ g.setColor(oldColor);
+ loadIcons();
+ Icon icon = fImage == null ? sMissingImageIcon : sPendingImageIcon;
+ if (icon != null)
+ icon.paintIcon(getContainer(), g, x, y);
+ }
+
+ // Draw image:
+ if (fImage != null)
+ {
+ g.drawImage(fImage, x, y, width, height, this);
+ // Use the following instead of g.drawImage when
+ // BufferedImageGraphics2D.setXORMode is fixed (4158822).
+
+ // Use Xor mode when selected/highlighted.
+ // ! Could darken image instead, but it would be more expensive.
+ /*
+ * if( sel > 0 ) g.setXORMode(Color.white); g.drawImage(fImage,x, y,
+ * width,height,this); if( sel > 0 ) g.setPaintMode();
+ */
+ }
+
+ // If selected exactly, we need a black border & grow-box:
+ Color bc = getBorderColor();
+ if (sel == 2)
+ {
+ // Make sure there's room for a border:
+ int delta = 2 - border;
+ if (delta > 0)
+ {
+ x += delta;
+ y += delta;
+ width -= delta << 1;
+ height -= delta << 1;
+ border = 2;
+ }
+ bc = null;
+ g.setColor(Color.black);
+ // Draw grow box:
+ g.fillRect(x + width - 5, y + height - 5, 5, 5);
+ }
+
+ // Draw border:
+ if (border > 0)
+ {
+ if (bc != null)
+ g.setColor(bc);
+ // Draw a thick rectangle:
+ for (int i = 1; i <= border; i++)
+ g.drawRect(x - i, y - i, width - 1 + i + i, height - 1 + i + i);
+ g.setColor(oldColor);
+ }
+ }
+
+ /**
+ * Request that this view be repainted. Assumes the view is still at its
+ * last-drawn location.
+ */
+ protected void repaint(long delay)
+ {
+ if (fContainer != null && fBounds != null)
+ {
+ fContainer.repaint(delay, fBounds.x, fBounds.y, fBounds.width,
+ fBounds.height);
+ }
+ }
+
+ /**
+ * Determines whether the image is selected, and if it's the only thing
+ * selected.
+ *
+ * @return 0 if not selected, 1 if selected, 2 if exclusively selected.
+ * "Exclusive" selection is only returned when editable.
+ */
+ protected int getSelectionState()
+ {
+ int p0 = fElement.getStartOffset();
+ int p1 = fElement.getEndOffset();
+ if (fContainer instanceof JTextComponent)
+ {
+ JTextComponent textComp = (JTextComponent) fContainer;
+ int start = textComp.getSelectionStart();
+ int end = textComp.getSelectionEnd();
+ if (start <= p0 && end >= p1)
+ {
+ if (start == p0 && end == p1 && isEditable())
+ return 2;
+ else
+ return 1;
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Checks whether the container is editable.
+ *
+ * @return true if the container is editable,
+ * false otherwise.
+ */
+ protected boolean isEditable()
+ {
+ return fContainer instanceof JEditorPane
+ && ((JEditorPane) fContainer).isEditable();
+ }
+
+ /**
+ * Returns the text editor's highlight color.
+ */
+ protected Color getHighlightColor()
+ {
+ JTextComponent textComp = (JTextComponent) fContainer;
+ return textComp.getSelectionColor();
+ }
+
+ // --- Progressive display ---------------------------------------------
+
+ // This can come on any thread. If we are in the process of reloading
+ // the image and determining our state (loading == true) we don't fire
+ // preference changed, or repaint, we just reset the fWidth/fHeight as
+ // necessary and return. This is ok as we know when loading finishes
+ // it will pick up the new height/width, if necessary.
+ public boolean imageUpdate(Image img, int flags, int x, int y, int width,
+ int height)
+ {
+ if (fImage == null || fImage != img)
+ return false;
+
+ // Bail out if there was an error:
+ if ((flags & (ABORT | ERROR)) != 0)
+ {
+ fImage = null;
+ repaint(0);
+ return false;
+ }
+
+ // Resize image if necessary:
+ short changed = 0;
+ if ((flags & ImageObserver.HEIGHT) != 0)
+ if (!getElement().getAttributes().isDefined(HTML.Attribute.HEIGHT))
+ {
+ changed |= 1;
+ }
+ if ((flags & ImageObserver.WIDTH) != 0)
+ if (!getElement().getAttributes().isDefined(HTML.Attribute.WIDTH))
+ {
+ changed |= 2;
+ }
+ synchronized (this)
+ {
+ if ((changed & 1) == 1)
+ {
+ fWidth = width;
+ }
+ if ((changed & 2) == 2)
+ {
+ fHeight = height;
+ }
+ if (loading)
+ {
+ // No need to resize or repaint, still in the process of
+ // loading.
+ return true;
+ }
+ }
+ if (changed != 0)
+ {
+ // May need to resize myself, asynchronously:
+ Document doc = getDocument();
+ try
+ {
+ if (doc instanceof AbstractDocument)
+ {
+ ((AbstractDocument) doc).readLock();
+ }
+ preferenceChanged(this, true, true);
+ } finally
+ {
+ if (doc instanceof AbstractDocument)
+ {
+ ((AbstractDocument) doc).readUnlock();
+ }
+ }
+
+ return true;
+ }
+
+ // Repaint when done or when new pixels arrive:
+ if ((flags & (FRAMEBITS | ALLBITS)) != 0)
+ repaint(0);
+ else if ((flags & SOMEBITS) != 0)
+ if (sIsInc)
+ repaint(sIncRate);
+
+ return ((flags & ALLBITS) == 0);
+ }
+
+ /*
+ * Static properties for incremental drawing. Swiped from Component.java
+ *
+ * @see #imageUpdate
+ */
+ private static boolean sIsInc = true;
+
+ private static int sIncRate = 100;
+
+ // --- Layout ----------------------------------------------------------
+
+ /**
+ * Determines the preferred span for this view along an axis.
+ *
+ * @param axis
+ * may be either X_AXIS or Y_AXIS
+ * @return the span the view would like to be rendered into. Typically the
+ * view is told to render into the span that is returned, although
+ * there is no guarantee. The parent may choose to resize or break
+ * the view.
+ */
+ public float getPreferredSpan(int axis)
+ {
+ int extra = 2 * (getBorder() + getSpace(axis));
+ switch (axis)
+ {
+ case View.X_AXIS:
+ return fWidth + extra;
+ case View.Y_AXIS:
+ return fHeight + extra;
+ default:
+ throw new IllegalArgumentException("Invalid axis: " + axis);
+ }
+ }
+
+ /**
+ * Determines the desired alignment for this view along an axis. This is
+ * implemented to give the alignment to the bottom of the icon along the y
+ * axis, and the default along the x axis.
+ *
+ * @param axis
+ * may be either X_AXIS or Y_AXIS
+ * @return the desired alignment. This should be a value between 0.0 and 1.0
+ * where 0 indicates alignment at the origin and 1.0 indicates
+ * alignment to the full span away from the origin. An alignment of
+ * 0.5 would be the center of the view.
+ */
+ public float getAlignment(int axis)
+ {
+ switch (axis)
+ {
+ case View.Y_AXIS:
+ return getVerticalAlignment();
+ default:
+ return super.getAlignment(axis);
+ }
+ }
+
+ /**
+ * Provides a mapping from the document model coordinate space to the
+ * coordinate space of the view mapped to it.
+ *
+ * @param pos
+ * the position to convert
+ * @param a
+ * the allocated region to render into
+ * @return the bounding box of the given position
+ * @exception BadLocationException
+ * if the given position does not represent a valid
+ * location in the associated document
+ * @see View#modelToView
+ */
+ public Shape modelToView(int pos, Shape a, Position.Bias b)
+ throws BadLocationException
+ {
+ int p0 = getStartOffset();
+ int p1 = getEndOffset();
+ if ((pos >= p0) && (pos <= p1))
+ {
+ Rectangle r = a.getBounds();
+ if (pos == p1)
+ {
+ r.x += r.width;
+ }
+ r.width = 0;
+ return r;
+ }
+ return null;
+ }
+
+ /**
+ * Provides a mapping from the view coordinate space to the logical
+ * coordinate space of the model.
+ *
+ * @param x
+ * the X coordinate
+ * @param y
+ * the Y coordinate
+ * @param a
+ * the allocated region to render into
+ * @return the location within the model that best represents the given
+ * point of view
+ * @see View#viewToModel
+ */
+ public int viewToModel(float x, float y, Shape a, Position.Bias[] bias)
+ {
+ Rectangle alloc = (Rectangle) a;
+ if (x < alloc.x + alloc.width)
+ {
+ bias[0] = Position.Bias.Forward;
+ return getStartOffset();
+ }
+ bias[0] = Position.Bias.Backward;
+ return getEndOffset();
+ }
+
+ /**
+ * Set the size of the view. (Ignored.)
+ *
+ * @param width
+ * the width
+ * @param height
+ * the height
+ */
+ public void setSize(float width, float height)
+ {
+ // Ignore this -- image size is determined by the tag attrs and
+ // the image itself, not the surrounding layout!
+ }
+
+ // --- Static icon accessors -------------------------------------------
+
+ private Icon makeIcon(final String gifFile) throws IOException
+ {
+ /*
+ * Copy resource into a byte array. This is necessary because several
+ * browsers consider Class.getResource a security risk because it can be
+ * used to load additional classes. Class.getResourceAsStream just
+ * returns raw bytes, which we can convert to an image.
+ */
+ InputStream resource = SIPCommImageView.class
+ .getResourceAsStream(gifFile);
+
+ if (resource == null)
+ {
+ logger.error(SIPCommImageView.class.getName() + "/" + gifFile
+ + " not found.");
+ return null;
+ }
+ BufferedInputStream in = new BufferedInputStream(resource);
+ ByteArrayOutputStream out = new ByteArrayOutputStream(1024);
+ byte[] buffer = new byte[1024];
+ int n;
+ while ((n = in.read(buffer)) > 0)
+ {
+ out.write(buffer, 0, n);
+ }
+ in.close();
+ out.flush();
+
+ buffer = out.toByteArray();
+ if (buffer.length == 0)
+ {
+ logger.error(gifFile + " is zero-length.");
+ return null;
+ }
+ return new ImageIcon(buffer);
+ }
+
+ private void loadIcons()
+ {
+ try
+ {
+ if (sPendingImageIcon == null)
+ sPendingImageIcon = makeIcon(PENDING_IMAGE_SRC);
+ if (sMissingImageIcon == null)
+ sMissingImageIcon = makeIcon(MISSING_IMAGE_SRC);
+ } catch (Exception ex)
+ {
+ logger.error("Couldn't load image icons.", ex);
+ }
+ }
+
+ protected StyleSheet getStyleSheet()
+ {
+ HTMLDocument doc = (HTMLDocument) getDocument();
+ return doc.getStyleSheet();
+ }
+
+ // --- member variables ------------------------------------------------
+
+ private AttributeSet attr;
+
+ private Element fElement;
+
+ private Image fImage;
+
+ private int fHeight, fWidth;
+
+ private Container fContainer;
+
+ private Rectangle fBounds;
+
+ private Component fComponent;
+
+ private Point fGrowBase; // base of drag while growing image
+
+ private boolean fGrowProportionally; // should grow be proportional?
+
+ /**
+ * Set to true, while the receiver is locked, to indicate the reciever is
+ * loading the image. This is used in imageUpdate.
+ */
+ private boolean loading;
+
+ // --- constants and static stuff --------------------------------
+
+ private static Icon sPendingImageIcon, sMissingImageIcon;
+
+ private static final String PENDING_IMAGE_SRC = "icons/image-delayed.gif", // both
+ // stolen
+ // from
+ // HotJava
+ MISSING_IMAGE_SRC = "icons/image-failed.gif";
+
+ // $ move this someplace public
+ static final String IMAGE_CACHE_PROPERTY = "imageCache";
+
+ // Height/width to use before we know the real size:
+ private static final int DEFAULT_WIDTH = 32, DEFAULT_HEIGHT = 32,
+ // Default value of BORDER param: //? possibly move into stylesheet?
+ DEFAULT_BORDER = 2;
+
+}
diff --git a/src/net/java/sip/communicator/plugin/splashscreen/SplashScreenActivator.java b/src/net/java/sip/communicator/plugin/splashscreen/SplashScreenActivator.java
index 7710bf3c8..339e0cc28 100644
--- a/src/net/java/sip/communicator/plugin/splashscreen/SplashScreenActivator.java
+++ b/src/net/java/sip/communicator/plugin/splashscreen/SplashScreenActivator.java
@@ -6,54 +6,133 @@
*/
package net.java.sip.communicator.plugin.splashscreen;
-import net.java.sip.communicator.service.gui.*;
+import java.awt.event.*;
+
+import javax.swing.JMenuItem;
+
+import net.java.sip.communicator.service.gui.UIService;
import org.osgi.framework.*;
-public class SplashScreenActivator
- implements BundleActivator,
- ServiceListener,
- BundleListener
+public class SplashScreenActivator implements BundleActivator, BundleListener
{
private WelcomeWindow welcomeWindow;
- private BundleContext bundleContext;
-
- public void start(BundleContext bundleContext) throws Exception
+ private static BundleContext bundleContext;
+ private JMenuItem aboutEntry;
+
+ public void start(BundleContext bc) throws Exception
{
- this.bundleContext = bundleContext;
-
+ bundleContext = bc;
+
welcomeWindow = new WelcomeWindow();
-
welcomeWindow.pack();
welcomeWindow.setVisible(true);
-
- this.bundleContext.addServiceListener(this);
- this.bundleContext.addBundleListener(this);
+
+ bundleContext.addBundleListener(this);
}
public void stop(BundleContext arg0) throws Exception
{
-
+ unRegisterMenuEntry();
}
- public void serviceChanged(ServiceEvent evt)
- {
- ServiceReference serviceRef = evt.getServiceReference();
-
- if(serviceRef.getBundle().getState() != Bundle.STARTING)
+ public void bundleChanged(BundleEvent evt)
+ {
+ if (welcomeWindow != null && welcomeWindow.isShowing()
+ && evt.getType() == BundleEvent.STARTED)
+ welcomeWindow.setBundle(evt.getBundle().getHeaders().get(
+ "Bundle-Name").toString());
+
+ ServiceReference[] services = evt.getBundle().getRegisteredServices();
+ if (services == null)
+ {
return;
-
- if (bundleContext.getServiceReference(UIService.class.getName())
- == serviceRef)
+ }
+ for (ServiceReference serviceRef : services)
{
- this.welcomeWindow.close();
+ ServiceReference uiServiceRef = bundleContext
+ .getServiceReference(UIService.class.getName());
+ if (serviceRef == uiServiceRef)
+ {
+ int state = serviceRef.getBundle().getState();
+ if (state == Bundle.ACTIVE)
+ {
+ // UI-Service started.
+
+ // register the about dialog menu entry
+ registerMenuEntry(uiServiceRef);
+
+ welcomeWindow.close();
+ }
+ }
}
+
}
- public void bundleChanged(BundleEvent evt)
+ private void registerMenuEntry(ServiceReference uiServiceRef)
{
- if(welcomeWindow != null && welcomeWindow.isShowing())
- welcomeWindow.setBundle(evt.getBundle().getHeaders()
- .get("Bundle-Name").toString());
- }
+ final UIService uiService = (UIService) bundleContext
+ .getService(uiServiceRef);
+
+ // add menu entry to file menu
+ // Add your menu item to the help menu
+ if (aboutEntry == null)
+ {
+ aboutEntry = new JMenuItem(Resources.getString("menuEntry"));
+ aboutEntry.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+
+ AboutWindow aboutWindow = new AboutWindow(null);
+ aboutWindow.setVisible(true);
+ }
+ });
+ }
+ // Check if the help menu is a supported container.
+ if (uiService.isContainerSupported(UIService.CONTAINER_HELP_MENU))
+ {
+ uiService.addComponent(UIService.CONTAINER_HELP_MENU, aboutEntry);
+ }
+ // Check if the help menu is a supported container.
+ if (uiService.isContainerSupported(UIService.CONTAINER_CHAT_HELP_MENU))
+ {
+ uiService.addComponent(UIService.CONTAINER_CHAT_HELP_MENU,
+ aboutEntry);
+ }
+ }
+
+ private void unRegisterMenuEntry()
+ {
+ // Obtain the UI Service
+ ServiceReference uiServiceRef = bundleContext
+ .getServiceReference(UIService.class.getName());
+
+ if (uiServiceRef == null
+ || uiServiceRef.getBundle().getState() != Bundle.ACTIVE)
+ {
+ return;
+ }
+
+ UIService uiService = (UIService) bundleContext
+ .getService(uiServiceRef);
+
+ // Check if the tools menu is a supported container.
+ boolean isContainerSupported = uiService
+ .isContainerSupported(UIService.CONTAINER_HELP_MENU);
+
+ if (isContainerSupported)
+ {
+ // add menu entry to file menu
+ // Add your menu item to the help menu
+ uiService
+ .removeComponent(UIService.CONTAINER_HELP_MENU, aboutEntry);
+ }
+ }
+
+ static BundleContext getBundleContext()
+ {
+ return bundleContext;
+ }
+
}
diff --git a/src/net/java/sip/communicator/plugin/splashscreen/StyledHTMLEditorPane.java b/src/net/java/sip/communicator/plugin/splashscreen/StyledHTMLEditorPane.java
new file mode 100644
index 000000000..9502a89ae
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/splashscreen/StyledHTMLEditorPane.java
@@ -0,0 +1,70 @@
+/*
+ * SIP Communicator, 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.splashscreen;
+
+import java.io.IOException;
+
+import javax.swing.JEditorPane;
+import javax.swing.text.*;
+import javax.swing.text.html.*;
+
+import net.java.sip.communicator.util.Logger;
+
+public class StyledHTMLEditorPane
+ extends JEditorPane
+{
+ private Logger logger = Logger.getLogger(StyledHTMLEditorPane.class);
+
+ private HTMLEditorKit editorKit = new SIPCommHTMLEditorKit();
+
+ private HTMLDocument document;
+
+ public StyledHTMLEditorPane()
+ {
+ this.document = (HTMLDocument) editorKit.createDefaultDocument();
+
+ this.setContentType("text/html");
+ this.setEditorKitForContentType("text/html", editorKit);
+ this.setEditorKit(editorKit);
+ this.setDocument(document);
+
+ Constants.loadSimpleStyle(document.getStyleSheet());
+ }
+
+
+ public void appendToEnd(String text)
+ {
+ Element root = document.getDefaultRootElement();
+ try
+ {
+ document.insertAfterEnd(root
+ .getElement(root.getElementCount() - 1), text);
+ }
+ catch (BadLocationException e)
+ {
+ logger.error("Insert in the HTMLDocument failed.", e);
+ }
+ catch (IOException e)
+ {
+ logger.error("Insert in the HTMLDocument failed.", e);
+ }
+ }
+
+ public void insertAfterStart(String text)
+ {
+ Element root = this.document.getDefaultRootElement();
+
+ try {
+ this.document.insertBeforeStart(root
+ .getElement(0), text);
+ } catch (BadLocationException e) {
+ logger.error("Insert in the HTMLDocument failed.", e);
+ } catch (IOException e) {
+ logger.error("Insert in the HTMLDocument failed.", e);
+ }
+ }
+}
diff --git a/src/net/java/sip/communicator/plugin/splashscreen/WindowBackground.java b/src/net/java/sip/communicator/plugin/splashscreen/WindowBackground.java
index 014a0b514..78331ef49 100644
--- a/src/net/java/sip/communicator/plugin/splashscreen/WindowBackground.java
+++ b/src/net/java/sip/communicator/plugin/splashscreen/WindowBackground.java
@@ -12,7 +12,6 @@
public class WindowBackground
extends JPanel
{
-
private Image bgImage;
public WindowBackground()
@@ -22,7 +21,7 @@ public WindowBackground()
try
{
bgImage = ImageIO.read(WindowBackground.class
- .getResource("aboutWindowBackground.png"));
+ .getResource("resources/aboutWindowBackground.png"));
}
catch (IOException e)
{
diff --git a/src/net/java/sip/communicator/plugin/splashscreen/WindowTransparentBackground.java b/src/net/java/sip/communicator/plugin/splashscreen/WindowTransparentBackground.java
index d428070d9..cbdbc9a0c 100644
--- a/src/net/java/sip/communicator/plugin/splashscreen/WindowTransparentBackground.java
+++ b/src/net/java/sip/communicator/plugin/splashscreen/WindowTransparentBackground.java
@@ -75,7 +75,7 @@ public WindowTransparentBackground() {
robot = new Robot();
bgImage = ImageIO.read(
- WindowBackground.class.getResource("aboutWindowBackground.png"));
+ WindowBackground.class.getResource("resources/aboutWindowBackground.png"));
bgWidth = bgImage.getWidth(null);
diff --git a/src/net/java/sip/communicator/plugin/splashscreen/resources.properties b/src/net/java/sip/communicator/plugin/splashscreen/resources.properties
index fb2d24e15..2b903aa71 100644
--- a/src/net/java/sip/communicator/plugin/splashscreen/resources.properties
+++ b/src/net/java/sip/communicator/plugin/splashscreen/resources.properties
@@ -1,3 +1,6 @@
+about=About
logoMessage=Open Source VoIP & Instant Messaging
loading=Loading
-welcomeMessage=The SIP Communicator is currently under active development. The version you are running is only experimental and MAY NOT work as expected. Please refer to {0} for more information.
\ No newline at end of file
+menuEntry=About
+ok=OK
+welcomeMessage=The SIP Communicator is currently under active development. The version you are running is only experimental and MAY NOT work as expected. Please refer to {0} for more information.
diff --git a/src/net/java/sip/communicator/plugin/splashscreen/resources/aboutWindowBackground.png b/src/net/java/sip/communicator/plugin/splashscreen/resources/aboutWindowBackground.png
new file mode 100644
index 000000000..4a178171d
Binary files /dev/null and b/src/net/java/sip/communicator/plugin/splashscreen/resources/aboutWindowBackground.png differ
diff --git a/src/net/java/sip/communicator/plugin/splashscreen/resources/defaultStyle.css b/src/net/java/sip/communicator/plugin/splashscreen/resources/defaultStyle.css
new file mode 100644
index 000000000..a9326a68c
--- /dev/null
+++ b/src/net/java/sip/communicator/plugin/splashscreen/resources/defaultStyle.css
@@ -0,0 +1,71 @@
+h1
+{
+background-color:#c6d0e1;
+margin:0px;
+text-align:center;
+font-weight:bold;
+font-size:12
+}
+
+h2
+{
+margin:0px;
+font-family:Verdana;
+font-size:12;
+color:#ef7b1e
+}
+
+h3
+{
+margin:0px;
+font-family:Verdana;
+font-size:12;
+color:#2e538b
+}
+
+h4
+{
+margin:0px;
+font-family:Verdana;
+font-size:12;
+font-weight:bold;
+color:#FFC875
+}
+
+h5
+{
+margin:0px;
+font-family:Verdana;
+font-size:12;
+font-weight:bold;
+color:#CC0000
+}
+
+h6
+{
+margin:0px;
+font-family:Verdana;
+font-size:12;
+font-weight:bold;
+color:#990000
+}
+p
+{
+margin:0px;
+font-family:Verdana;
+font-size:12;
+font-weight:bold;
+color:#62BD80
+}
+
+div
+{
+font-family:Verdana;
+font-size:12;
+color:#000000
+}
+
+i
+{
+background-color:#FFF4AB
+}
\ No newline at end of file
diff --git a/src/net/java/sip/communicator/plugin/splashscreen/aboutWindowBackground.png b/src/net/java/sip/communicator/plugin/splashscreen/resources/splashScreenBackground.png
similarity index 100%
rename from src/net/java/sip/communicator/plugin/splashscreen/aboutWindowBackground.png
rename to src/net/java/sip/communicator/plugin/splashscreen/resources/splashScreenBackground.png
diff --git a/src/net/java/sip/communicator/plugin/splashscreen/splashscreen.manifest.mf b/src/net/java/sip/communicator/plugin/splashscreen/splashscreen.manifest.mf
index 0ac55f24c..12cd0c270 100755
--- a/src/net/java/sip/communicator/plugin/splashscreen/splashscreen.manifest.mf
+++ b/src/net/java/sip/communicator/plugin/splashscreen/splashscreen.manifest.mf
@@ -4,8 +4,13 @@ Bundle-Description: Splash Screen plugin.
Bundle-Vendor: sip-communicator.org
Bundle-Version: 0.0.1
Import-Package: org.osgi.framework,
+ net.java.sip.communicator.service.browserlauncher,
net.java.sip.communicator.service.gui,
net.java.sip.communicator.service.gui.event,
+ net.java.sip.communicator.util,
javax.swing,
javax.swing.event,
+ javax.swing.border,
+ javax.swing.text,
+ javax.swing.text.html,
javax.imageio