From ef52168563518610a2defe5d3ebdff7bd546e716 Mon Sep 17 00:00:00 2001 From: Yana Stamcheva Date: Wed, 26 Jul 2006 18:09:52 +0000 Subject: [PATCH] Icq Account Registration Wizard --- build.xml | 12 +- lib/oscar.client.run.properties | 5 +- .../plugin/icqaccregwizz/FirstWizardPage.java | 172 ++++++++++++++++++ .../icqaccregwizz/IcqAccRegWizzActivator.java | 38 ++++ .../icqaccregwizz/IcqAccountRegistration.java | 40 ++++ .../IcqAccountRegistrationWizard.java | 61 +++++++ .../plugin/icqaccregwizz/Resources.java | 86 +++++++++ .../icqaccregwizz/SecondWizardPage.java | 48 +++++ .../icqaccregwizz/icqaccregwizz.manifest.mf | 31 ++++ .../plugin/icqaccregwizz/resources.properties | 10 + .../plugin/icqaccregwizz/resources/Icq.png | Bin 0 -> 6386 bytes 11 files changed, 501 insertions(+), 2 deletions(-) create mode 100644 src/net/java/sip/communicator/plugin/icqaccregwizz/FirstWizardPage.java create mode 100644 src/net/java/sip/communicator/plugin/icqaccregwizz/IcqAccRegWizzActivator.java create mode 100644 src/net/java/sip/communicator/plugin/icqaccregwizz/IcqAccountRegistration.java create mode 100644 src/net/java/sip/communicator/plugin/icqaccregwizz/IcqAccountRegistrationWizard.java create mode 100644 src/net/java/sip/communicator/plugin/icqaccregwizz/Resources.java create mode 100644 src/net/java/sip/communicator/plugin/icqaccregwizz/SecondWizardPage.java create mode 100644 src/net/java/sip/communicator/plugin/icqaccregwizz/icqaccregwizz.manifest.mf create mode 100644 src/net/java/sip/communicator/plugin/icqaccregwizz/resources.properties create mode 100644 src/net/java/sip/communicator/plugin/icqaccregwizz/resources/Icq.png diff --git a/build.xml b/build.xml index 1939bbde9..180462c56 100644 --- a/build.xml +++ b/build.xml @@ -511,7 +511,7 @@ bundle-slick-runner,bundle-sip,bundle-fileaccess, bundle-fileaccess-slick,bundle-media,bundle-media-slick, bundle-protocol,bundle-icq,bundle-icq-slick,bundle-mock,bundle-swing-ui, - meta-contactlist,meta-contactlist-slick"/> + meta-contactlist,meta-contactlist-slick,bundle-plugin-icqaccregwizz"/> @@ -801,5 +801,15 @@ javax.swing.event, javax.swing.border"/> prefix="net/java/sip/communicator/slick/contactlist"/> + + + + + + + + diff --git a/lib/oscar.client.run.properties b/lib/oscar.client.run.properties index 9751fb469..5a64c2935 100644 --- a/lib/oscar.client.run.properties +++ b/lib/oscar.client.run.properties @@ -56,8 +56,11 @@ oscar.auto.start.4= \ file:sc-bundles/msghistory.jar - oscar.auto.start.99= \ + oscar.auto.start.66= \ file:sc-bundles/swing-ui.jar + + oscar.auto.start.67= \ + file:sc-bundles/icqaccregwizz.jar # Uncomment the following lines if you want to run the architect viewer # bundle. diff --git a/src/net/java/sip/communicator/plugin/icqaccregwizz/FirstWizardPage.java b/src/net/java/sip/communicator/plugin/icqaccregwizz/FirstWizardPage.java new file mode 100644 index 000000000..2ecab098c --- /dev/null +++ b/src/net/java/sip/communicator/plugin/icqaccregwizz/FirstWizardPage.java @@ -0,0 +1,172 @@ +/* + * 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.icqaccregwizz; + +import java.awt.BorderLayout; +import java.awt.Dimension; +import java.awt.FlowLayout; +import java.awt.GridLayout; + +import javax.swing.BorderFactory; +import javax.swing.BoxLayout; +import javax.swing.JButton; +import javax.swing.JCheckBox; +import javax.swing.JLabel; +import javax.swing.JPanel; +import javax.swing.JPasswordField; +import javax.swing.JTextArea; +import javax.swing.JTextField; +import javax.swing.event.DocumentEvent; +import javax.swing.event.DocumentListener; + +import net.java.sip.communicator.service.gui.WizardContainer; +import net.java.sip.communicator.service.gui.WizardPage; + +public class FirstWizardPage extends JPanel + implements WizardPage, DocumentListener { + + public static final String FIRST_PAGE_IDENTIFIER = "FirstPageIdentifier"; + + private JPanel uinPassPanel = new JPanel(new BorderLayout(10, 10)); + + private JPanel labelsPanel = new JPanel(new GridLayout(0, 1, 10, 10)); + + private JPanel valuesPanel = new JPanel(new GridLayout(0, 1, 10, 10)); + + private JLabel uinLabel = new JLabel(Resources.getString("uin")); + + private JLabel passLabel = new JLabel(Resources.getString("password")); + + private JTextField uinField = new JTextField(); + + private JPasswordField passField = new JPasswordField(); + + private JCheckBox rememberPassBox = new JCheckBox( + Resources.getString("rememberPassword")); + + private JPanel registerPanel = new JPanel(new GridLayout(0, 1)); + + private JPanel buttonPanel = new JPanel( + new FlowLayout(FlowLayout.CENTER)); + + private JTextArea registerArea = new JTextArea( + Resources.getString("registerNewAccountText")); + + private JButton registerButton = new JButton( + Resources.getString("registerNewAccount")); + + private JPanel mainPanel = new JPanel(); + + private IcqAccountRegistration registration; + + private WizardContainer wizardContainer; + + public FirstWizardPage(IcqAccountRegistration registration, + WizardContainer wizardContainer) { + + super(new BorderLayout()); + + this.wizardContainer = wizardContainer; + + this.registration = registration; + + this.setPreferredSize(new Dimension(300, 150)); + + mainPanel.setLayout(new BoxLayout(mainPanel, BoxLayout.Y_AXIS)); + + this.init(); + } + + private void init() { + this.uinField.getDocument().addDocumentListener(this); + + labelsPanel.add(uinLabel); + labelsPanel.add(passLabel); + + valuesPanel.add(uinField); + valuesPanel.add(passField); + + uinPassPanel.add(labelsPanel, BorderLayout.WEST); + uinPassPanel.add(valuesPanel, BorderLayout.CENTER); + uinPassPanel.add(rememberPassBox, BorderLayout.SOUTH); + + uinPassPanel.setBorder(BorderFactory + .createTitledBorder(Resources.getString("uinAndPassword"))); + + mainPanel.add(uinPassPanel); + + this.buttonPanel.add(registerButton); + + this.registerArea.setLineWrap(true); + this.registerArea.setWrapStyleWord(true); + + this.registerPanel.add(registerArea); + this.registerPanel.add(buttonPanel); + + this.registerPanel.setBorder(BorderFactory + .createTitledBorder(Resources.getString("registerNewAccount"))); + + mainPanel.add(registerPanel); + + this.add(mainPanel, BorderLayout.NORTH); + } + + public Object getIdentifier() { + return FIRST_PAGE_IDENTIFIER; + } + + public Object getNextPageIdentifier() { + return WizardPage.SUMMARY_PAGE_IDENTIFIER; + } + + public Object getBackPageIdentifier() { + return WizardPage.DEFAULT_PAGE_IDENTIFIER; + } + + public Object getWizardForm() { + return this; + } + + public void pageHiding() { + } + + public void pageShown() { + } + + public void pageShowing() { + this.setNextButtonAccordingToUIN(); + } + + public void pageNext() { + registration.setUin(uinField.getText()); + registration.setPassword(passField.getPassword().toString()); + registration.setRememberPassword(rememberPassBox.isSelected()); + } + + public void pageBack() { + } + + private void setNextButtonAccordingToUIN() { + if (uinField.getText() == null || uinField.getText().equals("")) { + wizardContainer.setNextFinishButtonEnabled(false); + } + else { + wizardContainer.setNextFinishButtonEnabled(true); + } + } + + public void insertUpdate(DocumentEvent e) { + this.setNextButtonAccordingToUIN(); + } + + public void removeUpdate(DocumentEvent e) { + this.setNextButtonAccordingToUIN(); + } + + public void changedUpdate(DocumentEvent e) { + } +} diff --git a/src/net/java/sip/communicator/plugin/icqaccregwizz/IcqAccRegWizzActivator.java b/src/net/java/sip/communicator/plugin/icqaccregwizz/IcqAccRegWizzActivator.java new file mode 100644 index 000000000..487e9c0bd --- /dev/null +++ b/src/net/java/sip/communicator/plugin/icqaccregwizz/IcqAccRegWizzActivator.java @@ -0,0 +1,38 @@ +/* + * 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.icqaccregwizz; + +import net.java.sip.communicator.service.gui.AccountRegistrationWizardContainer; +import net.java.sip.communicator.service.gui.UIService; +import net.java.sip.communicator.service.gui.WizardContainer; + +import org.osgi.framework.BundleActivator; +import org.osgi.framework.BundleContext; +import org.osgi.framework.ServiceReference; + +public class IcqAccRegWizzActivator implements BundleActivator { + + public void start(BundleContext bundleContext) throws Exception { + ServiceReference uiServiceRef = bundleContext + .getServiceReference(UIService.class.getName()); + + UIService uiService + = (UIService) bundleContext.getService(uiServiceRef); + + AccountRegistrationWizardContainer wizardContainer + = uiService.getAccountRegWizardContainer(); + + IcqAccountRegistrationWizard icqWizard + = new IcqAccountRegistrationWizard(wizardContainer); + + wizardContainer.addAccountRegistrationWizard(icqWizard); + } + + public void stop(BundleContext bundleContext) throws Exception { + + } +} diff --git a/src/net/java/sip/communicator/plugin/icqaccregwizz/IcqAccountRegistration.java b/src/net/java/sip/communicator/plugin/icqaccregwizz/IcqAccountRegistration.java new file mode 100644 index 000000000..ff0723f52 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/icqaccregwizz/IcqAccountRegistration.java @@ -0,0 +1,40 @@ +/* + * 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.icqaccregwizz; + +public class IcqAccountRegistration { + + private String uin; + + private String password; + + private boolean rememberPassword; + + public String getPassword() { + return password; + } + + public void setPassword(String password) { + this.password = password; + } + + public boolean isRememberPassword() { + return rememberPassword; + } + + public void setRememberPassword(boolean rememberPassword) { + this.rememberPassword = rememberPassword; + } + + public String getUin() { + return uin; + } + + public void setUin(String uin) { + this.uin = uin; + } +} diff --git a/src/net/java/sip/communicator/plugin/icqaccregwizz/IcqAccountRegistrationWizard.java b/src/net/java/sip/communicator/plugin/icqaccregwizz/IcqAccountRegistrationWizard.java new file mode 100644 index 000000000..1c158beec --- /dev/null +++ b/src/net/java/sip/communicator/plugin/icqaccregwizz/IcqAccountRegistrationWizard.java @@ -0,0 +1,61 @@ +/* + * 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.icqaccregwizz; + +import java.util.ArrayList; +import java.util.Hashtable; +import java.util.Iterator; + +import net.java.sip.communicator.service.gui.AccountRegistrationWizard; +import net.java.sip.communicator.service.gui.AccountRegistrationWizardContainer; +import net.java.sip.communicator.service.gui.WizardContainer; + +public class IcqAccountRegistrationWizard implements AccountRegistrationWizard { + + private FirstWizardPage firstWizardPage; + + private ArrayList pages = new ArrayList(); + + private IcqAccountRegistration registration + = new IcqAccountRegistration(); + + public IcqAccountRegistrationWizard(WizardContainer wizardContainer) { + firstWizardPage = new FirstWizardPage(registration, wizardContainer); + + pages.add(firstWizardPage); + } + + public byte[] getIcon() { + return Resources.getImage(Resources.ICQ_LOGO); + } + + public String getProtocolName() { + return Resources.getString("protocolName"); + } + + public String getProtocolDescription() { + return Resources.getString("protocolDescription"); + } + + public Iterator getPages() { + return pages.iterator(); + } + + public Iterator getSummary() { + Hashtable summaryTable = new Hashtable(); + + summaryTable.put("UIN", registration.getUin()); + summaryTable.put("Remember password", + new Boolean(registration.isRememberPassword())); + + return summaryTable.entrySet().iterator(); + } + + public void finish() { + System.out.println("FINISH!!!!!!!!!!!!!!!!!!"); + } +} diff --git a/src/net/java/sip/communicator/plugin/icqaccregwizz/Resources.java b/src/net/java/sip/communicator/plugin/icqaccregwizz/Resources.java new file mode 100644 index 000000000..fcefa01f0 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/icqaccregwizz/Resources.java @@ -0,0 +1,86 @@ +/* + * 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.icqaccregwizz; + +import java.awt.image.BufferedImage; +import java.io.FileInputStream; +import java.io.IOException; +import java.util.MissingResourceException; +import java.util.ResourceBundle; + +import javax.imageio.ImageIO; + +import net.java.sip.communicator.util.Logger; +/** + * The Messages class manages the access to the internationalization + * properties files. + * @author Yana Stamcheva + */ +public class Resources { + + private static Logger log = Logger.getLogger(Resources.class); + + private static final String BUNDLE_NAME + = "net.java.sip.communicator.plugin.icqaccregwizz.resources"; + + private static final ResourceBundle RESOURCE_BUNDLE = ResourceBundle + .getBundle(BUNDLE_NAME); + + public static ImageID ICQ_LOGO = new ImageID("protocolIcon"); + + /** + * Returns an internationalized string corresponding to the given key. + * @param key The key of the string. + * @return An internationalized string corresponding to the given key. + */ + public static String getString(String key) { + try { + return RESOURCE_BUNDLE.getString(key); + + } catch (MissingResourceException e) { + + return '!' + key + '!'; + } + } + + /** + * Loads an image from a given image identifier. + * @param imageID The identifier of the image. + * @return The image for the given identifier. + */ + public static byte[] getImage(ImageID imageID) { + byte[] image = new byte[100000]; + + String path = Resources.getString(imageID.getId()); + try { + Resources.class.getClassLoader() + .getResourceAsStream(path).read(image); + + } catch (IOException e) { + log.error("Failed to load image:" + path, e); + } + + return image; + } + + /** + * Represents the Image Identifier. + */ + public static class ImageID { + private String id; + + private ImageID(String id) { + this.id = id; + } + + public String getId() { + return id; + } + } + +} diff --git a/src/net/java/sip/communicator/plugin/icqaccregwizz/SecondWizardPage.java b/src/net/java/sip/communicator/plugin/icqaccregwizz/SecondWizardPage.java new file mode 100644 index 000000000..93a5349f8 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/icqaccregwizz/SecondWizardPage.java @@ -0,0 +1,48 @@ +/* + * 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.icqaccregwizz; + +import javax.swing.JPanel; + +import net.java.sip.communicator.service.gui.WizardPage; + +public class SecondWizardPage extends JPanel + implements WizardPage { + + public static final String SECOND_PAGE_IDENTIFIER = "SecondPageIdentifier"; + + public Object getIdentifier() { + return SECOND_PAGE_IDENTIFIER; + } + + public Object getNextPageIdentifier() { + return FINISH_PAGE_IDENTIFIER; + } + + public Object getBackPageIdentifier() { + return FirstWizardPage.FIRST_PAGE_IDENTIFIER; + } + + public Object getWizardForm() { + return this; + } + + public void pageHiding() { + } + + public void pageShown() { + } + + public void pageShowing() { + } + + public void pageNext() { + } + + public void pageBack() { + } +} diff --git a/src/net/java/sip/communicator/plugin/icqaccregwizz/icqaccregwizz.manifest.mf b/src/net/java/sip/communicator/plugin/icqaccregwizz/icqaccregwizz.manifest.mf new file mode 100644 index 000000000..3229d68b6 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/icqaccregwizz/icqaccregwizz.manifest.mf @@ -0,0 +1,31 @@ +Bundle-Activator: net.java.sip.communicator.plugin.icqaccregwizz.IcqAccRegWizzActivator +Bundle-Name: ICQ account registration wizard +Bundle-Description: ICQ account registration wizard. +Bundle-Vendor: sip-communicator.org +Bundle-Version: 0.0.1 +Import-Package: org.osgi.framework, + net.java.sip.communicator.util, + net.java.sip.communicator.service.configuration, + net.java.sip.communicator.service.configuration.event, + net.java.sip.communicator.service.protocol, + net.java.sip.communicator.service.protocol.icqconstants, + net.java.sip.communicator.service.protocol.event, + net.java.sip.communicator.service.contactlist, + net.java.sip.communicator.service.contactlist.event, + net.java.sip.communicator.service.gui, + net.java.sip.communicator.service.gui.event, + javax.swing, + javax.swing.event, + javax.swing.table, + javax.swing.text, + javax.swing.text.html, + javax.accessibility, + javax.swing.plaf, + javax.swing.plaf.metal, + javax.swing.plaf.basic, + javax.imageio, + javax.swing.filechooser, + javax.swing.tree, + javax.swing.undo, + javax.swing.event, + javax.swing.border diff --git a/src/net/java/sip/communicator/plugin/icqaccregwizz/resources.properties b/src/net/java/sip/communicator/plugin/icqaccregwizz/resources.properties new file mode 100644 index 000000000..675a15b32 --- /dev/null +++ b/src/net/java/sip/communicator/plugin/icqaccregwizz/resources.properties @@ -0,0 +1,10 @@ +protocolName=ICQ +protocolDescription=The AOL ICQ service protocol +uin=ICQ UIN: +password=Password: +rememberPassword=Remember password +uinAndPassword=UIN and Password +registerNewAccount=Register new account +registerNewAccountText=In case you don't have an ICQ account, click on this button to create a new one. + +protocolIcon=net/java/sip/communicator/plugin/icqaccregwizz/resources/Icq.png \ No newline at end of file diff --git a/src/net/java/sip/communicator/plugin/icqaccregwizz/resources/Icq.png b/src/net/java/sip/communicator/plugin/icqaccregwizz/resources/Icq.png new file mode 100644 index 0000000000000000000000000000000000000000..6a3d1549f4e6a11aa5edaeb2a2790941cba76eaa GIT binary patch literal 6386 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