225fc10380e370034c432c16cb5a36706e8ba21f
[FinalKeyGui.git] / src / fkgui / MainWin.java
1 package fkgui;
2
3
4 import java.io.IOException;
5 import java.net.URI;
6 import java.net.URISyntaxException;
7 import java.util.Map;
8 import java.util.Vector;
9 import  java.util.prefs.*;
10 import java.awt.*;
11 import java.awt.event.ActionEvent;
12 import java.awt.event.ActionListener;
13
14 import javax.swing.SwingUtilities;
15 import javax.swing.UIManager;
16
17 import org.eclipse.jface.viewers.DoubleClickEvent;
18 import org.eclipse.jface.viewers.IDoubleClickListener;
19 import org.eclipse.jface.viewers.ISelectionChangedListener;
20 import org.eclipse.jface.viewers.ListViewer;
21 import org.eclipse.jface.viewers.SelectionChangedEvent;
22 import org.eclipse.jface.viewers.StructuredSelection;
23 import org.eclipse.swt.widgets.Display;
24 import org.eclipse.swt.widgets.Event;
25 import org.eclipse.swt.widgets.Listener;
26 import org.eclipse.swt.widgets.MessageBox;
27 import org.eclipse.swt.widgets.Shell;
28 import org.eclipse.swt.widgets.Button;
29 import org.eclipse.swt.SWT;
30 import org.eclipse.swt.events.ControlEvent;
31 import org.eclipse.swt.events.ControlListener;
32 import org.eclipse.swt.events.FocusEvent;
33 import org.eclipse.swt.events.FocusListener;
34 import org.eclipse.swt.events.KeyEvent;
35 import org.eclipse.swt.events.KeyListener;
36 import org.eclipse.swt.events.ModifyEvent;
37 import org.eclipse.swt.events.ModifyListener;
38 import org.eclipse.swt.events.SelectionAdapter;
39 import org.eclipse.swt.events.SelectionEvent;
40 import org.eclipse.swt.events.SelectionListener;
41 import org.eclipse.swt.events.ShellEvent;
42 import org.eclipse.swt.events.ShellListener;
43 import org.eclipse.swt.events.VerifyEvent;
44 import org.eclipse.swt.events.VerifyListener;
45 import org.eclipse.swt.graphics.Color;
46 import org.eclipse.swt.graphics.Device;
47 import org.eclipse.swt.widgets.Text;
48 import org.eclipse.swt.widgets.Label;
49 import org.eclipse.swt.widgets.Control;
50 import org.eclipse.wb.swt.SWTResourceManager;
51
52 import fkgui.FkManager.Account;
53 import fkgui.SerialWorker.SerialState;
54 import fkgui.UpdateChecker.UpdateCheckResultListener;
55
56 import org.eclipse.swt.widgets.TabFolder;
57 import org.eclipse.swt.widgets.TabItem;
58 import org.eclipse.swt.widgets.Composite;
59 import org.eclipse.swt.layout.FormLayout;
60 import org.eclipse.swt.layout.FormData;
61 import org.eclipse.swt.layout.FormAttachment;
62 import org.eclipse.swt.layout.FillLayout;
63 import org.eclipse.swt.widgets.List;
64 import org.eclipse.swt.awt.SWT_AWT;
65 import org.eclipse.swt.custom.CCombo;
66 import org.eclipse.swt.widgets.Combo;
67 import org.eclipse.swt.widgets.Group;
68
69 public class MainWin implements ConsoleMsg, UpdateCheckResultListener {
70
71         protected Shell shell;
72         private Text txtPsw;
73         public TrayIcon trayIcon;
74         public PopupMenu popup;
75         public MenuItem showMain;
76         public MenuItem hideMain;
77         public MenuItem exitApp;
78
79         public Text txtLog;
80         public Button btnConnect;
81         public Label lblPort;
82         public Label lblPassword;
83         
84         public Animation animation;
85         
86         public TabFolder tabFolder;
87
88         private Text txtDev;
89         Preferences prefs;
90         MainWin mySelf;
91         
92         SerialWorker fkSerial;
93         private boolean sysTrayIconVisible;
94         
95         Button btnOpenAccount;
96         private Color blackColor;
97         private Color grayColor;
98         private Color defaultBgColor;
99         private Color greenColor;
100         private Color redColor;
101         
102         private static final String PREF_PORT ="lastUsedPortPref"; //$NON-NLS-1$
103         private static final String PREF_DEFAULT_DEVICE = "/dev/FinalKey"; //$NON-NLS-1$
104         private static final String PREF_AUTOHIDE = "hideMainWinAfterConnect"; //$NON-NLS-1$
105         private static final String PREF_SORT_BY_ID_KEY = "sortAccountListById"; //$NON-NLS-1$
106         private static final String PREF_SHOW_ACCOUNT_ID_IN_NAME_KEY = "showAccountIdInName"; //$NON-NLS-1$
107         private static final String PREF_ALLOW_UPDATE_CHECK = "allowUpdateCheck"; //$NON-NLS-1$
108         private static final String PREF_SHOW_ACCOUNTS_READY_NOTICE = "showAccountsReadyNotice"; //$NON-NLS-1$
109         private static final String PREF_SHOW_SYSTRAY_NAME = "showSystrayName"; //$NON-NLS-1$
110         private static final String PREF_HIDE_ON_CLOSE = "hideToSysTrayOnMainWinClose"; //$NON-NLS-1$
111
112         public Composite cmpConnect;
113         private Composite cmpAccounts;
114         ListViewer lstAccounts;
115         private List lstAccountsControl;
116         Label lblNumFree;
117         Button btnNewAccount;
118         Button chkCheckForUpdates;
119         Boolean hiddenAtStart=false;
120         Button btnShowaccountsReady;
121  
122         //Icons
123         private org.eclipse.swt.graphics.Image iconProgramOnline  = SWTResourceManager.getImage(MainWin.class, "/fkgui/gfx/finalkey.png");  //$NON-NLS-1$
124         private org.eclipse.swt.graphics.Image iconProgramOffline  = SWTResourceManager.getImage(MainWin.class, "/fkgui/gfx/finalkey-big-offline.png");  //$NON-NLS-1$
125         private Image iconSystrayOnline = Toolkit.getDefaultToolkit().createImage(getClass().getResource("gfx/systray-color.png"));  //$NON-NLS-1$
126         private Image iconSystrayOffline= Toolkit.getDefaultToolkit().createImage(getClass().getResource("gfx/systray-offline.png"));  //$NON-NLS-1$
127
128         private TabItem tbtmAccounts;
129         private TabItem tbtmSettings;
130         private Composite cmpSettings;
131         private Button chkAutoHide;
132         private Button chkSortByAccountId;
133         private Button chkShowAccountId;
134         private Thread updateCheckThread;
135         private Text txtFilter;
136         
137         String systrayTipTxt;
138         private Button btnHideToTrayOnClose;
139         private TabItem tbtmThisFinalkey;
140         private Composite composite;
141         private Text txtBanner; 
142         private Combo cmbLayout;
143         private Group grpBackupAndRestore;
144         private Group group_1;
145         private Label label;
146         private Text text_1;
147         private Text text_2;
148         private Text text_3;
149         private Label label_1;
150         private Label label_2;
151         private Label label_3;
152         private Button button;
153         private Group grpFormat;
154         private Label lblNewLabel;
155         private Button btnNewButton;
156         private Button btnNewButton_1;
157         
158         private Button btnFkSettingsSave;
159         private Label lblMakeSureYou;
160
161         
162         
163         /**
164          * Launch the application.
165          * @param args
166          */
167         public static void main(String[] args) {
168
169                 try {
170                         MainWin window = new MainWin();
171
172                         for(String s : args )
173                         {
174                                 if( s.compareTo("--hide") == 0 ) //$NON-NLS-1$
175                                 {
176                                         window.hiddenAtStart=true;
177                                 }
178                         }
179
180                         window.open();
181                 } catch (Exception e) {
182                         e.printStackTrace();
183                 }
184                 
185         }
186
187         /**
188          * Open the window.
189          */
190         public void open() {
191                 Display display = Display.getDefault();
192                 createContents();
193
194                 serialEvent(SerialState.Disconnected);
195                 
196                 shell.getDisplay().addFilter(SWT.KeyDown, new Listener() {
197                         
198                         @Override
199                         public void handleEvent(Event arg0) {
200                                 if( ( (arg0.stateMask&SWT.CTRL) == SWT.CTRL) && arg0.keyCode == 'f'  )
201                                 {
202                                         if( tabFolder.getItemCount() == 3 && !txtFilter.isFocusControl() )
203                                         {
204                                                 tabFolder.setSelection(1);
205                                                 txtFilter.setFocus();
206                                         }
207                                 }
208                                 
209                         }
210                 });
211
212
213                 checkForUpdates();
214
215                 if( hiddenAtStart )
216                 {
217                         hideToTray();
218                 } else {
219                         shell.open();
220                         shell.layout();
221                 }
222
223                 clearSystray(true);
224                 
225                 while (!shell.isDisposed()) {
226                         if (!display.readAndDispatch()) {
227                                 display.sleep();
228                         }
229                 }
230         }
231         
232         private void checkForUpdates() {
233                 if( prefs.getBoolean(PREF_ALLOW_UPDATE_CHECK, true) )
234                 {
235                         if( updateCheckThread == null )
236                         {
237                                 updateCheckThread = new Thread(new UpdateChecker(this));
238                                 updateCheckThread.start();
239                         } else {
240                                 System.out.println(Messages.MainWin_0);
241                         }
242                 } else {
243                         System.out.println(Messages.MainWin_3);
244                 }
245         }
246
247         public void log( String str )
248         {
249                 txtLog.append(str+"\n"); //$NON-NLS-1$
250                 if( tabFolder.getSelectionIndex() == 0 )
251                 {
252                         txtLog.redraw();
253                         shell.redraw();
254                 }
255                 System.out.println(str);
256
257         }
258
259         /**
260          * Create a systemTray icon
261          */
262         private void createSysTrayIcon()
263         {
264                 sysTrayIconVisible=true;
265                 //Check the SystemTray is supported
266                 if (!SystemTray.isSupported()) {
267                         log("SystemTray is not supported."); //$NON-NLS-1$
268                         return;
269                 }
270
271                 try {
272                         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
273                 } catch (Exception e1) {
274                         e1.printStackTrace();
275                 }
276
277                 popup = new PopupMenu();
278                 trayIcon = new TrayIcon( iconSystrayOffline ); //$NON-NLS-1$
279
280                 trayIcon.setImageAutoSize(true);
281                 final SystemTray tray = SystemTray.getSystemTray();
282
283                 // Create a pop-up menu components
284                 showMain = new MenuItem(Messages.MainWin_7);
285                 hideMain = new MenuItem(Messages.MainWin_8);
286                 exitApp  = new MenuItem("Quit");
287
288                 showMain.addActionListener(new ActionListener() {
289                         @Override
290                         public void actionPerformed(ActionEvent e) {
291                                 Display.getDefault().syncExec( new Runnable(){
292
293                                         public void run()
294                                         {
295                                                 showFromTray();
296                                         }
297                                 } );
298                         }
299
300                 });
301
302                 hideMain.addActionListener(new ActionListener() {
303                         @Override
304                         public void actionPerformed(ActionEvent e) {
305                                 Display.getDefault().syncExec( new Runnable(){
306
307                                         public void run()
308                                         {
309                                                 hideToTray();
310                                         }
311                                 } );
312                         }
313                 });
314
315                 exitApp.addActionListener(new ActionListener() {
316                         @Override
317                         public void actionPerformed(ActionEvent e) {
318                                 Display.getDefault().asyncExec( new Runnable(){
319
320                                         public void run()
321                                         {
322                                                 shutDownApp();
323                                         }
324                                 } );
325                         }
326                 });             
327                 
328                 trayIcon.setPopupMenu(popup);
329
330                 try {
331                         tray.add(trayIcon);
332                 } catch (AWTException e) {
333                         log("TrayIcon could not be added."); //$NON-NLS-1$
334                 }
335
336         }
337
338         private void setSystrayIconTip(String tip) {
339                 if( tip == null )
340                 {
341                         trayIcon.setToolTip(systrayTipTxt);
342                 } else {
343                         systrayTipTxt=tip;
344                         trayIcon.setToolTip(tip);
345                 }
346
347                 if( !prefs.getBoolean(PREF_SHOW_SYSTRAY_NAME, true) )
348                 {
349                         trayIcon.setToolTip(null);
350                 }
351
352         }
353
354         private void hideToTray()
355         {
356                 popup.remove(0);
357                 popup.insert(showMain, 0);
358                 shell.setVisible(false);
359         }
360
361         private void showFromTray()
362         {
363                 popup.remove(0);
364                 popup.insert(hideMain, 0);
365                 shell.setVisible(true);
366                 shell.forceActive();
367         }
368
369         private void destroySysTrayIcon()
370         {
371                 sysTrayIconVisible=false;
372                 SystemTray.getSystemTray().remove(trayIcon);
373         }
374
375         private void clearSystray(Boolean addExitBtn) {
376                         popup.removeAll();
377                         //Add components to pop-up menu
378                         if(shell.isVisible()==true)
379                         {
380                                 popup.add(hideMain);
381                         } else {
382                                 popup.add(showMain);
383                         }
384                         popup.addSeparator();
385
386                         if(addExitBtn)
387                         {
388                                 popup.add(exitApp);
389                         }
390         }
391
392         public void shutDownApp()
393         {
394                 if(fkSerial != null)
395                 {
396                         fkSerial.disconnect();
397                 }
398                 if(sysTrayIconVisible == true)
399                 {
400                         destroySysTrayIcon();
401                 }
402                 System.exit(0);
403         }
404
405         /**
406          * Create contents of the window.
407          */
408         
409
410         /*uint8_t EncryptedStorage::crc8(const uint8_t *addr, uint8_t len)
411         {
412                 uint8_t crc = 0;
413
414                 while (len--) {
415                         uint8_t inbyte = *addr++;
416                         for (uint8_t i = 8; i; i--) {
417                                 uint8_t mix = (crc ^ inbyte) & 0x01;
418                                 crc >>= 1;
419                                 if (mix) crc ^= 0x8C;
420                                 inbyte >>= 1;
421                         }
422                 }
423                 return crc;
424         } */
425         
426         
427         protected void createContents() {
428
429
430                 shell = new Shell();
431                 shell.setImage( iconProgramOffline ); //$NON-NLS-1$
432                 shell.setSize(711, 655);
433
434                 prefs = Preferences.userNodeForPackage(this.getClass());
435
436                 FkManager.getInstance().sortById( prefs.getBoolean(PREF_SORT_BY_ID_KEY, false) );
437
438                 mySelf = this;
439                 shell.setLayout(new FillLayout(SWT.HORIZONTAL));
440
441                 tabFolder = new TabFolder(shell, SWT.NONE);
442                 tabFolder.setBackground(SWTResourceManager.getColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));
443
444                 TabItem tbtmConnection = new TabItem(tabFolder, SWT.NONE);
445                 tbtmConnection.setText(Messages.MainWin_12);
446
447                 cmpConnect = new Composite(tabFolder, SWT.BORDER);
448                 tbtmConnection.setControl(cmpConnect);
449                 cmpConnect.setLayout(new FormLayout());
450
451                 btnConnect = new Button(cmpConnect, SWT.CENTER);
452                 btnConnect.setImage( SWTResourceManager.getImage(MainWin.class, "/fkgui/gfx/lightning.png") ); //$NON-NLS-1$
453                 FormData fd_btnConnect = new FormData();
454                 fd_btnConnect.top = new FormAttachment(0, 8);
455                 fd_btnConnect.left = new FormAttachment(100, -125);
456                 fd_btnConnect.right = new FormAttachment(100, -10);
457
458                 btnConnect.setLayoutData(fd_btnConnect);
459
460                 btnConnect.addSelectionListener(new SelectionAdapter() {
461                         public void widgetSelected(SelectionEvent e) {
462
463                                 if( fkSerial!=null && fkSerial.state == SerialState.Connected )
464                                 {
465                                         fkSerial.disconnect();
466                                 } else {
467                                         connect();
468                                 }
469                         }
470
471                 });
472                 btnConnect.setText(Messages.MainWin_15);
473                 txtPsw = new Text(cmpConnect, SWT.BORDER | SWT.PASSWORD);
474                 FormData fd_txtPsw = new FormData();
475
476                 fd_txtPsw.left = new FormAttachment(0, 102);
477                 txtPsw.setLayoutData(fd_txtPsw);
478                 txtPsw.setFocus();
479                 txtPsw.addKeyListener( new KeyListener() {
480                         @Override
481                         public void keyReleased(KeyEvent arg0) { }
482
483                         @Override
484                         public void keyPressed(KeyEvent arg0) {
485                                 if( arg0.character==SWT.CR )
486                                 {
487                                         connect();
488                                 }
489                         }
490                 });
491
492                 txtLog = new Text(cmpConnect, SWT.BORDER | SWT.V_SCROLL | SWT.MULTI | SWT.WRAP);
493                 fd_btnConnect.bottom = new FormAttachment(txtPsw, 0, SWT.BOTTOM);
494                 FormData fd_txtLog = new FormData();
495                 fd_txtLog.bottom = new FormAttachment(100, -8);
496                 fd_txtLog.top = new FormAttachment(btnConnect, 8, SWT.BOTTOM);
497                 fd_txtLog.left = new FormAttachment(0, 8);
498                 fd_txtLog.right = new FormAttachment(btnConnect,0, SWT.RIGHT);
499                 txtLog.setLayoutData(fd_txtLog);
500                 txtLog.setEditable(false);
501
502                 lblPort = new Label(cmpConnect, SWT.NONE);
503                 lblPort.setAlignment(SWT.RIGHT);
504                 FormData fd_lblPort = new FormData();
505                 fd_lblPort.left = new FormAttachment(0, 10);
506                 lblPort.setLayoutData(fd_lblPort);
507                 lblPort.setText(Messages.MainWin_4);
508
509                 txtDev = new Text(cmpConnect, SWT.BORDER);
510                 fd_txtPsw.top = new FormAttachment(txtDev,4, SWT.BOTTOM);
511                 fd_lblPort.top = new FormAttachment(txtDev,0,SWT.CENTER);
512                 fd_lblPort.right = new FormAttachment(txtDev, -7);
513                 FormData fd_txtDev = new FormData();
514                 fd_txtDev.top = new FormAttachment(btnConnect,0,SWT.TOP);
515                 fd_txtDev.left = new FormAttachment(0, 102);
516                 txtDev.setLayoutData(fd_txtDev);
517                 txtDev.setText( prefs.get(PREF_PORT, PREF_DEFAULT_DEVICE));
518                 lblPassword = new Label(cmpConnect, SWT.NONE);
519                 lblPassword.setAlignment(SWT.RIGHT);
520                 FormData fd_lblPassword = new FormData();
521                 fd_lblPassword.right = new FormAttachment(0, 95);
522                 fd_lblPassword.top = new FormAttachment(txtPsw, 0, SWT.CENTER);
523                 fd_lblPassword.left = new FormAttachment(0, 10);
524                 lblPassword.setLayoutData(fd_lblPassword);
525                 lblPassword.setText(Messages.MainWin_18);
526
527                 animation = new Animation(cmpConnect, SWT.NONE, 4);
528                 fd_txtDev.right = new FormAttachment(animation,-16, SWT.LEFT );
529                 fd_txtPsw.right = new FormAttachment(animation,-16, SWT.LEFT );
530
531                 FormData fd_animation = new FormData();
532                 fd_animation.right = new FormAttachment(btnConnect, -16);
533                 fd_animation.top = new FormAttachment(0, 10);
534
535                 animation.setLayoutData(fd_animation);
536
537                 animation.setVisible(false);
538                 animation.setPlaying(false);
539                 cmpConnect.setTabList(new Control[]{txtPsw, btnConnect, txtDev});
540
541                 log(Messages.MainWin_22);
542
543
544                 //
545                 shell.addListener(SWT.Close, new Listener() {
546                         @Override
547                         public void handleEvent(Event arg0) {
548                                 if( prefs.getBoolean(PREF_HIDE_ON_CLOSE, true))
549                                 {
550                                         arg0.doit=false;
551                                         hideToTray();
552                                 } else {
553                                         shutDownApp();
554                                 }
555                         }
556                 });
557
558
559                 if( System.getProperty("os.name").compareTo("Linux") == 0 ) //$NON-NLS-1$ //$NON-NLS-2$
560                 {
561                         Boolean gtkOk=false;
562                         Map<String, String> env = System.getenv();
563                         for (String envName : env.keySet()) {
564                                 if( envName.compareTo("SWT_GTK3") == 0 && env.get(envName).compareTo("0") == 0 ) //$NON-NLS-1$ //$NON-NLS-2$
565                                 {
566                                         gtkOk=true;
567                                 }
568                         }
569
570                         if( !gtkOk )
571                         {
572                                 log("Warning: Enviroment variable SWT_GTK3 is not set to 0, if FinalKey GUI looks weird or crashes after connecting, try export GTK_SWT3=0 before running."); //$NON-NLS-1$
573                         }
574                 }
575
576                 Device display = Display.getCurrent();
577                 blackColor = display.getSystemColor(SWT.COLOR_BLACK );
578                 grayColor = display.getSystemColor(SWT.COLOR_GRAY );
579                 defaultBgColor = display.getSystemColor(SWT.COLOR_LIST_BACKGROUND );
580                 greenColor = display.getSystemColor(SWT.COLOR_DARK_GREEN );
581                 redColor = display.getSystemColor(SWT.COLOR_RED );
582
583                 
584                 //
585                 addSettingsTab();
586                 addThisFkTab();
587                 addAccountsTab();
588                 createSysTrayIcon();
589         }
590
591
592         private void connect() {
593                 fkSerial = new SerialWorker(mySelf);
594                 prefs.put(PREF_PORT, txtDev.getText() );
595                 fkSerial.connect(txtDev.getText(),txtPsw.getText());
596                 txtPsw.setText(""); //$NON-NLS-1$
597         }
598
599         @Override
600         public void updateAccountList()
601         {
602                 int free=256;
603                 clearSystray(false);
604                 lstAccounts.getList().removeAll();
605
606                 Boolean showAccountId = prefs.getBoolean( PREF_SHOW_ACCOUNT_ID_IN_NAME_KEY, false);
607
608                 for( FkManager.Account a : FkManager.getInstance().getList() )
609                 {
610                         free--;
611                         lstAccounts.add( a.showNumInName( showAccountId ) );
612
613                         //populate the popup
614                         Menu menu = new Menu(a.toString());
615                         MenuItem both = new MenuItem(Messages.MainWin_25);
616                         MenuItem usr = new MenuItem(Messages.MainWin_26);
617                         MenuItem psw = new MenuItem(Messages.MainWin_27);
618                         menu.add(both);
619                         menu.add(usr);
620                         menu.add(psw);
621
622
623                         both.addActionListener(FkManager.getInstance());
624                         both.setActionCommand( "%"+a.num ); //$NON-NLS-1$
625
626
627
628                         psw.addActionListener(FkManager.getInstance()); 
629                         psw.setActionCommand( "p"+a.num); //$NON-NLS-1$
630
631
632                         usr.addActionListener(FkManager.getInstance()); 
633                         usr.setActionCommand( "u"+a.num ); //$NON-NLS-1$
634
635                         popup.add(menu);
636                 }
637                 
638                 //Add the exit button
639                 popup.addSeparator();
640                 popup.add(exitApp);
641
642                 lblNumFree.setText(" "+free+Messages.MainWin_32); //$NON-NLS-1$
643                 lblNumFree.pack();
644                 lblNumFree.getParent().layout();
645
646                 if( free == 0 )
647                 {
648                         btnNewAccount.setVisible(false);
649                 } else {
650                         btnNewAccount.setVisible(true);
651                 }
652
653         }
654
655         @Override
656         public void serialEvent(SerialState state) {
657                 switch(state)
658                 {
659                 case Connected:
660                         shell.setText(Messages.MainWin_33 + FkManager.getInstance().getBanner());
661                         setSystrayIconTip(Messages.MainWin_33 + FkManager.getInstance().getBanner());
662
663                         animation.setVisible(false);
664                         animation.setPlaying(false);
665
666                         btnConnect.setText(Messages.MainWin_34);
667                         btnConnect.setEnabled(true);
668
669                         //Should we hide?
670                         if( prefs.getBoolean(PREF_AUTOHIDE, false) == true)
671                         {
672                                 hideToTray();
673                         }
674
675                         addThisFkTab();
676                         addAccountsTab();
677                         
678
679                         
680                         tabFolder.setSelection(tbtmAccounts);
681
682                         updateAccountList();
683                         txtFilter.setFocus();
684
685                         //Update icons for systray and window
686                         shell.setImage( iconProgramOnline );
687                         trayIcon.setImage( iconSystrayOnline );
688
689                         int numAccounts=FkManager.getInstance().getList().size();
690                         if( numAccounts>0 && prefs.getBoolean( PREF_SHOW_ACCOUNTS_READY_NOTICE, true) )
691                         {
692
693                                 class TrayIconMessageTask implements Runnable
694                                 {
695                                         private String msg;
696                                         public TrayIconMessageTask(String _msg)
697                                         {
698                                                 msg = _msg;
699                                         }
700                                         public void run()
701                                         {
702                                                 trayIcon.displayMessage("FinalKey", msg, //$NON-NLS-1$ //$NON-NLS-2$
703                                                                 TrayIcon.MessageType.INFO);
704                                         }
705                                 }
706
707                                 new Thread( new TrayIconMessageTask(numAccounts +" "+ (( numAccounts >1)?Messages.MainWin_1:Messages.MainWin_2)) ).start();
708
709                         }
710
711                 //      log(Messages.MainWin_40);
712
713                         break;
714                 case Connecting:
715                         shell.setText(Messages.MainWin_41);
716                         animation.setVisible(true);
717                         animation.setPlaying(true);
718
719                         txtPsw.setEnabled(false);
720                         txtDev.setEnabled(false);
721                         btnConnect.setEnabled(false);
722
723                         lblPort.setEnabled(false);
724                         lblPassword.setEnabled(false);
725                         break;
726                 case Disconnected:
727                         setSystrayIconTip("The Final Key - Not Connected"); //$NON-NLS-1$
728
729                         fkSerial=null;
730                         animation.setVisible(false);
731                         animation.setPlaying(false);
732
733                         remAccountsTab();
734                         remThisFkTab();
735
736                         tabFolder.setSelection(0);
737
738                         shell.setText(Messages.MainWin_42);
739                         btnConnect.setText(Messages.MainWin_43);
740
741                         btnConnect.setEnabled(true);
742
743                         lblPort.setEnabled(true);
744                         lblPassword.setEnabled(true);
745                         txtPsw.setEnabled(true);
746                         txtPsw.setFocus();
747                         txtDev.setEnabled(true);
748
749                         cmpConnect.update();
750
751                         clearSystray(true);
752
753                         //Update icons for systray and window
754                         shell.setImage( iconProgramOffline );
755                         trayIcon.setImage( iconSystrayOffline );
756                         break;
757
758                 case Working:
759                         animation.setPlaying(false);
760                         animation.setVisible(false);
761                         break;
762
763                 default:
764                         break;
765                 }
766                 cmpConnect.layout();
767         }
768
769         private void updateSettingsSaveBtnVisibility()
770         {
771                 boolean show=false;
772                 if( btnFkSettingsSave != null)
773                 {
774                         if( FkManager.getInstance().getBanner().compareTo( txtBanner.getText() ) != 0 )
775                         {
776                                 show=true;
777                         }
778
779                         if( cmbLayout.getSelectionIndex() != -1  && cmbLayout.getItem(cmbLayout.getSelectionIndex()).compareTo(FkManager.getInstance().getCurrentLayout()) != 0 )
780                         {
781                                 show=true;
782                         }
783
784                         if(show)
785                         {
786                                 btnFkSettingsSave.setEnabled(true);
787                         } else {
788                                 btnFkSettingsSave.setEnabled(false);
789                         }
790                 }
791         }
792
793         private void addThisFkTab()
794         {
795                 tbtmThisFinalkey = new TabItem(tabFolder, SWT.NONE,1);
796                 tbtmThisFinalkey.setText(Messages.MainWin_tbtmThisFinalkey_text);
797
798                 composite = new Composite(tabFolder, SWT.NONE);
799                 tbtmThisFinalkey.setControl(composite);
800                 composite.setLayout(new FormLayout());
801
802                 Group group = new Group(composite, SWT.NONE);
803                 group.setText(Messages.MainWin_group_text);
804                 group.setLayout(new FormLayout());
805                 FormData fd_group = new FormData();
806                 fd_group.bottom = new FormAttachment(0, 100);
807                 fd_group.top = new FormAttachment(0, 10);
808                 fd_group.left = new FormAttachment(0, 10);
809                 fd_group.right = new FormAttachment(100, -10);
810                 group.setLayoutData(fd_group);
811
812
813                 Label lblBannerName = new Label(group, SWT.NONE);
814                 lblBannerName.setAlignment(SWT.RIGHT);
815                 FormData fd_lblBannerName = new FormData();
816                 fd_lblBannerName.left = new FormAttachment(0, 10);
817                 fd_lblBannerName.top = new FormAttachment(0, 10);
818                 lblBannerName.setLayoutData(fd_lblBannerName);
819                 lblBannerName.setText(Messages.MainWin_lblBannerName_text);
820
821                 txtBanner = new Text(group, SWT.BORDER);
822                 fd_lblBannerName.right = new FormAttachment(txtBanner, -6);
823                 FormData fd_txtBanner = new FormData();
824                 fd_txtBanner.right = new FormAttachment(0, 455);
825                 fd_txtBanner.top = new FormAttachment(0, 10);
826                 fd_txtBanner.left = new FormAttachment(0, 149);
827                 txtBanner.setLayoutData(fd_txtBanner);
828                 txtBanner.setToolTipText(Messages.MainWin_text_1_toolTipText);
829                 txtBanner.setText(Messages.MainWin_text_1_text_1);
830                 txtBanner.addVerifyListener(new VerifyListener() {
831                         @Override
832                         public void verifyText(VerifyEvent arg0) {
833                                 System.out.println("Verify:"+arg0.text );
834                                 arg0.doit=false;
835                                 if(arg0.text.length()==0)
836                                 {
837                                         arg0.doit=true;
838                                 } else if( FkManager.getInstance().isStringValidForFk(arg0.text))
839                                 {
840                                         if(txtBanner.getText().length()+arg0.text.length() < 32) //Banner can be a max of 31 chars long.
841                                         {
842                                                 arg0.doit=true;
843                                         }
844                                 }
845                         }
846                 });
847                 txtBanner.addModifyListener( new ModifyListener() {
848                         @Override
849                         public void modifyText(ModifyEvent arg0) {
850                                 updateSettingsSaveBtnVisibility();
851                         }
852                 });
853
854                 //Populate with data from FkManager
855                 txtBanner.setText( FkManager.getInstance().getBanner() );
856
857                 Label lblKeyboardLayout = new Label(group, SWT.NONE);
858                 lblKeyboardLayout.setAlignment(SWT.RIGHT);
859                 FormData fd_lblKeyboardLayout = new FormData();
860                 fd_lblKeyboardLayout.left = new FormAttachment(0, 10);
861                 fd_lblKeyboardLayout.bottom = new FormAttachment(100, -13);
862                 lblKeyboardLayout.setLayoutData(fd_lblKeyboardLayout);
863                 lblKeyboardLayout.setText(Messages.MainWin_lblKeyboardLayout_text);
864
865                 cmbLayout = new Combo(group, SWT.READ_ONLY);
866                 fd_lblKeyboardLayout.right = new FormAttachment(cmbLayout, -6);
867                 FormData fd_cmbLayout = new FormData();
868                 fd_cmbLayout.bottom = new FormAttachment(100, -11);
869                 fd_cmbLayout.top = new FormAttachment(txtBanner, 6);
870                 fd_cmbLayout.right = new FormAttachment(0, 301);
871                 fd_cmbLayout.left = new FormAttachment(0, 149);
872                 cmbLayout.setLayoutData(fd_cmbLayout);
873                 cmbLayout.setItems( FkManager.getInstance().getAvailableLayouts() );
874                 cmbLayout.addSelectionListener( new SelectionListener() {
875                         
876                         @Override
877                         public void widgetSelected(SelectionEvent arg0) {
878                                 updateSettingsSaveBtnVisibility();
879                         }
880
881                         @Override
882                         public void widgetDefaultSelected(SelectionEvent arg0) {} 
883                 });
884
885                 cmbLayout.select( cmbLayout.indexOf(FkManager.getInstance().getCurrentLayout() ));
886
887                 grpBackupAndRestore = new Group(composite, SWT.NONE);
888                 grpBackupAndRestore.setText(Messages.MainWin_grpBackupAndRestore_text);
889                 grpBackupAndRestore.setLayout(new FormLayout());
890                 FormData fd_grpBackupAndRestore = new FormData();
891                 fd_grpBackupAndRestore.top = new FormAttachment(group, 6);
892                 fd_grpBackupAndRestore.left = new FormAttachment(0, 10);
893                 fd_grpBackupAndRestore.bottom = new FormAttachment(0, 243);
894                 fd_grpBackupAndRestore.right = new FormAttachment(100, -10);
895
896                 btnFkSettingsSave = new Button(group, SWT.NONE);
897                 btnFkSettingsSave.addSelectionListener(new SelectionAdapter() {
898                         @Override
899                         public void widgetSelected(SelectionEvent e) {
900                                 SaveSettingsDialog dialog = new SaveSettingsDialog(shell, shell.getStyle() );
901                                 shell.setEnabled(false);
902                                 
903                                 if( (FkManager.getInstance().getBanner().compareTo( txtBanner.getText() ) != 0) )
904                                 {
905                                         dialog.bannerTxt = txtBanner.getText();
906                                 }
907                                 
908                                 if( (cmbLayout.getSelectionIndex() != -1  && cmbLayout.getItem(cmbLayout.getSelectionIndex()).compareTo(FkManager.getInstance().getCurrentLayout()) != 0) )
909                                 {
910                                         dialog.Layout = cmbLayout.getSelectionIndex()+1; //FinalKey presents the layout choice between 1,2,3
911                                 }
912                                 
913                                 dialog.open();
914                                 shell.setEnabled(true);
915                                 updateSettingsSaveBtnVisibility();
916                                 
917                         }
918                 });
919                 FormData fd_btnSave = new FormData();
920                 fd_btnSave.right = new FormAttachment(txtBanner, 68, SWT.RIGHT);
921                 fd_btnSave.top = new FormAttachment(lblBannerName, 0, SWT.TOP);
922                 fd_btnSave.left = new FormAttachment(txtBanner, 6);
923                 btnFkSettingsSave.setLayoutData(fd_btnSave);
924                 btnFkSettingsSave.setText(Messages.MainWin_btnSave_text);
925                 grpBackupAndRestore.setLayoutData(fd_grpBackupAndRestore);
926                 btnFkSettingsSave.setEnabled(false);
927
928                 group_1 = new Group(composite, SWT.NONE);
929                 group_1.setText("Security");
930                 group_1.setLayout(new FormLayout());
931                 FormData fd_group_1 = new FormData();
932                 fd_group_1.bottom = new FormAttachment(grpBackupAndRestore, 197, SWT.BOTTOM);
933                 fd_group_1.top = new FormAttachment(grpBackupAndRestore, 6);
934
935                 Button btnBackup = new Button(grpBackupAndRestore, SWT.CENTER);
936                 btnBackup.setImage(SWTResourceManager.getImage(MainWin.class, "/fkgui/gfx/backup.png"));
937                 FormData fd_btnBackup = new FormData();
938                 fd_btnBackup.left = new FormAttachment(0, 10);
939                 fd_btnBackup.top = new FormAttachment(0, 10);
940                 fd_btnBackup.bottom = new FormAttachment(100, -28);
941                 btnBackup.setLayoutData(fd_btnBackup);
942                 btnBackup.setText(Messages.MainWin_btnBackupYourFinalkey_text);
943                 btnBackup.addSelectionListener(new SelectionAdapter() {
944                         @Override
945                         public void widgetSelected(SelectionEvent e) {
946                                 shell.setEnabled(false);;
947                                 Backup b = new Backup(shell, shell.getStyle() );
948                                 b.open(false);
949                                 shell.setEnabled(true);
950                         }
951                 });
952
953                 btnNewButton = new Button(grpBackupAndRestore, SWT.NONE);
954                 btnNewButton.setImage(SWTResourceManager.getImage(MainWin.class, "/fkgui/gfx/restore.png"));
955                 FormData fd_btnNewButton = new FormData();
956                 fd_btnNewButton.top = new FormAttachment(0, 10);
957                 fd_btnNewButton.right = new FormAttachment(100, -10);
958                 fd_btnNewButton.bottom = new FormAttachment(100, -28);
959                 btnNewButton.setLayoutData(fd_btnNewButton);
960                 btnNewButton.setText(Messages.MainWin_btnNewButton_text);
961                 btnNewButton.addSelectionListener(new SelectionAdapter() {
962                         @Override
963                         public void widgetSelected(SelectionEvent e) {
964                                 shell.setEnabled(false);;
965                                 Backup b = new Backup(shell, shell.getStyle() );
966                                 b.open(true);
967                                 shell.setEnabled(true);
968                         }
969                 });
970                 
971                 lblMakeSureYou = new Label(grpBackupAndRestore, SWT.NONE);
972                 fd_btnNewButton.left = new FormAttachment(lblMakeSureYou, 6);
973                 fd_btnBackup.right = new FormAttachment(100, -555);
974                 FormData fd_lblMakeSureYou = new FormData();
975                 fd_lblMakeSureYou.top = new FormAttachment(0, 10);
976                 fd_lblMakeSureYou.left = new FormAttachment(btnBackup, 6);
977                 fd_lblMakeSureYou.right = new FormAttachment(0, 541);
978                 fd_lblMakeSureYou.bottom = new FormAttachment(0, 92);
979                 lblMakeSureYou.setLayoutData(fd_lblMakeSureYou);
980                 lblMakeSureYou.setText(Messages.MainWin_lblMakeSureYou_text);
981                 fd_group_1.right = new FormAttachment(group, 0, SWT.RIGHT);
982                 fd_group_1.left = new FormAttachment(0, 10);
983                 group_1.setLayoutData(fd_group_1);
984
985                 label = new Label(group_1, SWT.NONE);
986                 label.setText("Always use a secure master-password, but don't forget it, you can not unlock\nyour FinalKey without it! Changing the password is risky, it can result in data-loss\nif the process is interrupted, you should take a backup before changing your\nmaster-password. Changing master-password takes a while as it re-encrypts accounts.");
987                 FormData fd_label = new FormData();
988                 fd_label.bottom = new FormAttachment(0, 79);
989                 fd_label.top = new FormAttachment(0, 10);
990                 fd_label.right = new FormAttachment(0, 675);
991                 fd_label.left = new FormAttachment(0, 10);
992                 label.setLayoutData(fd_label);
993
994                 text_1 = new Text(group_1, SWT.BORDER | SWT.PASSWORD);
995                 FormData fd_text_1 = new FormData();
996                 fd_text_1.top = new FormAttachment(label, 6);
997                 fd_text_1.right = new FormAttachment(0, 455);
998                 fd_text_1.left = new FormAttachment(0, 149);
999                 text_1.setLayoutData(fd_text_1);
1000
1001                 text_2 = new Text(group_1, SWT.BORDER | SWT.PASSWORD);
1002                 FormData fd_text_2 = new FormData();
1003                 fd_text_2.top = new FormAttachment(text_1, 6);
1004                 fd_text_2.right = new FormAttachment(0, 455);
1005                 fd_text_2.left = new FormAttachment(0, 149);
1006                 text_2.setLayoutData(fd_text_2);
1007
1008                 text_3 = new Text(group_1, SWT.BORDER | SWT.PASSWORD);
1009                 FormData fd_text_3 = new FormData();
1010                 fd_text_3.top = new FormAttachment(text_2, 6);
1011                 fd_text_3.right = new FormAttachment(text_1, 0, SWT.RIGHT);
1012                 fd_text_3.left = new FormAttachment(0, 149);
1013                 text_3.setLayoutData(fd_text_3);
1014
1015                 label_1 = new Label(group_1, SWT.NONE);
1016                 label_1.setText("Current Pass");
1017                 label_1.setAlignment(SWT.RIGHT);
1018                 FormData fd_label_1 = new FormData();
1019                 fd_label_1.top = new FormAttachment(label, 12);
1020                 fd_label_1.right = new FormAttachment(text_1, -6);
1021                 fd_label_1.left = new FormAttachment(label, 0, SWT.LEFT);
1022                 label_1.setLayoutData(fd_label_1);
1023
1024                 label_2 = new Label(group_1, SWT.NONE);
1025                 label_2.setText("New Pass");
1026                 label_2.setAlignment(SWT.RIGHT);
1027                 FormData fd_label_2 = new FormData();
1028                 fd_label_2.top = new FormAttachment(label_1, 12);
1029                 fd_label_2.right = new FormAttachment(text_2, -6);
1030                 fd_label_2.left = new FormAttachment(label, 0, SWT.LEFT);
1031                 label_2.setLayoutData(fd_label_2);
1032
1033                 label_3 = new Label(group_1, SWT.NONE);
1034                 label_3.setText("Repeat");
1035                 label_3.setAlignment(SWT.RIGHT);
1036                 FormData fd_label_3 = new FormData();
1037                 fd_label_3.top = new FormAttachment(label_2, 12);
1038                 fd_label_3.right = new FormAttachment(text_3, -6);
1039                 fd_label_3.left = new FormAttachment(text_3, -139, SWT.LEFT);
1040                 label_3.setLayoutData(fd_label_3);
1041
1042                 button = new Button(group_1, SWT.NONE);
1043                 button.setText("Re-encrypt");
1044                 FormData fd_button = new FormData();
1045                 fd_button.bottom = new FormAttachment(text_3, 0, SWT.BOTTOM);
1046                 fd_button.left = new FormAttachment(text_3, 6);
1047                 button.setLayoutData(fd_button);
1048
1049                 grpFormat = new Group(composite, SWT.NONE);
1050                 grpFormat.setText(Messages.MainWin_grpFormat_text);
1051                 FormData fd_grpFormat = new FormData();
1052                 fd_grpFormat.bottom = new FormAttachment(group_1, 69, SWT.BOTTOM);
1053                 fd_grpFormat.top = new FormAttachment(group_1, 6);
1054                 fd_grpFormat.right = new FormAttachment(group, 0, SWT.RIGHT);
1055                 fd_grpFormat.left = new FormAttachment(group, 0, SWT.LEFT);
1056                 grpFormat.setLayoutData(fd_grpFormat);
1057
1058                 lblNewLabel = new Label(grpFormat, SWT.NONE);
1059                 lblNewLabel.setBounds(10, 0, 366, 40);
1060                 lblNewLabel.setText(Messages.MainWin_lblNewLabel_text_1);
1061
1062                 btnNewButton_1 = new Button(grpFormat, SWT.NONE);
1063                 btnNewButton_1.setBounds(382, 10, 91, 26);
1064                 btnNewButton_1.setText(Messages.MainWin_btnNewButton_1_text);
1065
1066         }
1067         private void remThisFkTab() {
1068                 if(tbtmThisFinalkey != null)
1069                 {
1070                         tbtmThisFinalkey.dispose();
1071                 }
1072         }
1073
1074         private void remAccountsTab() {
1075                 if( tbtmAccounts != null )
1076                 {
1077                         tbtmAccounts.dispose();
1078                 }
1079
1080         }
1081
1082         void updateFilteredList(Vector<Account> source)
1083         {
1084                 lstAccounts.getList().removeAll();
1085
1086                 Boolean showAccountId = prefs.getBoolean( PREF_SHOW_ACCOUNT_ID_IN_NAME_KEY, false);
1087
1088                 for( FkManager.Account a : source )
1089                 {
1090                         lstAccounts.add( a.showNumInName( showAccountId ) );
1091                 }
1092         }
1093
1094         private void addAccountsTab() {
1095
1096                 tbtmAccounts = new TabItem(tabFolder, SWT.NONE, 1);//TabItem(tabFolder, SWT.NONE);
1097                 tbtmAccounts.setText(Messages.MainWin_45);
1098
1099                 cmpAccounts = new Composite(tabFolder, SWT.BORDER);
1100                 tbtmAccounts.setControl(cmpAccounts);
1101                 cmpAccounts.setLayout(new FormLayout());
1102
1103                 btnNewAccount = new Button(cmpAccounts, SWT.NONE);
1104                 btnNewAccount.setImage(SWTResourceManager.getImage(MainWin.class, "/fkgui/gfx/new.png")); //$NON-NLS-1$
1105                 btnNewAccount.addSelectionListener(new SelectionAdapter() {
1106                         @Override
1107                         public void widgetSelected(SelectionEvent e) {
1108                                 NewAccountDialog dialog = new NewAccountDialog(shell, shell.getStyle() );
1109                                 btnOpenAccount.setEnabled(false);
1110                                 shell.setEnabled(false);
1111                                 dialog.open();
1112                                 shell.setEnabled(true);
1113                                 updateAccountList();
1114                         }
1115                 });
1116                 FormData fd_btnNewAccoount = new FormData();
1117                 fd_btnNewAccoount.right = new FormAttachment(100, -10);
1118                 fd_btnNewAccoount.top = new FormAttachment(100, -40);
1119                 fd_btnNewAccoount.bottom = new FormAttachment(100, -6);
1120                 fd_btnNewAccoount.left = new FormAttachment(100, -200);
1121
1122                 btnNewAccount.setLayoutData(fd_btnNewAccoount);
1123                 btnNewAccount.setText(Messages.MainWin_47);
1124
1125                 lstAccounts = new ListViewer(cmpAccounts, SWT.BORDER | SWT.V_SCROLL);
1126                 lstAccountsControl = lstAccounts.getList();
1127                 lstAccountsControl.setLayoutData(new FormData());
1128
1129                 lblNumFree = new Label(cmpAccounts, SWT.NONE);
1130                 //lblNumFree.setText("Hello World!"); //$NON-NLS-1$
1131                 FormData fd_lblNumFree = new FormData();
1132                 fd_lblNumFree.left = new FormAttachment(lstAccountsControl,0,SWT.LEFT);
1133                 fd_lblNumFree.bottom = new FormAttachment(btnNewAccount, 0, SWT.CENTER);
1134                 lblNumFree.setLayoutData(fd_lblNumFree);
1135
1136                 btnOpenAccount = new Button(cmpAccounts, SWT.NONE);
1137                 //fd_lblNumFree.right = new FormAttachment(btnOpenAccount, -224);
1138                 btnOpenAccount.setImage(SWTResourceManager.getImage(MainWin.class, "/fkgui/gfx/lightbulb.png")); //$NON-NLS-1$
1139                 FormData fd_btnOpenAccount = new FormData();
1140                 fd_btnOpenAccount.top = new FormAttachment(btnNewAccount, 0, SWT.TOP);
1141                 fd_btnOpenAccount.bottom = new FormAttachment(btnNewAccount, 0, SWT.BOTTOM);
1142                 fd_btnOpenAccount.right = new FormAttachment(btnNewAccount, -8, SWT.LEFT );
1143                 btnOpenAccount.setLayoutData(fd_btnOpenAccount);
1144                 btnOpenAccount.setText(Messages.MainWin_5);
1145                 btnOpenAccount.getShell().layout();
1146                 btnOpenAccount.setEnabled(false);
1147
1148
1149                 FormData fd_lstAccounts = new FormData();
1150                 fd_lstAccounts.top = new FormAttachment(0, 8);
1151                 fd_lstAccounts.bottom = new FormAttachment(btnNewAccount, -6);
1152
1153                 txtFilter = new Text(cmpAccounts, SWT.BORDER);
1154                 txtFilter.setText(Messages.MainWin_10);
1155                 FormData fd_txtFilter = new FormData();
1156                 fd_txtFilter.left = new FormAttachment(lblNumFree, 8, SWT.RIGHT);
1157                 fd_txtFilter.bottom = new FormAttachment(btnOpenAccount,0, SWT.CENTER);
1158                 fd_txtFilter.right = new FormAttachment(btnOpenAccount, -8, SWT.LEFT);
1159                 txtFilter.setLayoutData(fd_txtFilter);
1160                 txtFilter.setForeground( grayColor );
1161                 txtFilter.addFocusListener( new FocusListener() {
1162                         @Override
1163                         public void focusLost(FocusEvent arg0) {
1164                                 txtFilter.setText(Messages.MainWin_10);
1165                                 txtFilter.setForeground( grayColor );
1166                                 txtFilter.setBackground( defaultBgColor );
1167                         }
1168
1169                         @Override
1170                         public void focusGained(FocusEvent arg0) {
1171                                 updateFilteredList( FkManager.getInstance().getList() );
1172                                 txtFilter.setForeground( blackColor );
1173                                 txtFilter.setText(""); //$NON-NLS-1$
1174                                 btnOpenAccount.setEnabled(false);
1175                         }
1176                 });
1177
1178                 txtFilter.addKeyListener( new KeyListener() {
1179
1180                         @Override
1181                         public void keyReleased(KeyEvent arg0) {
1182                                 if( arg0.keyCode == SWT.ESC )
1183                                 {
1184                                         txtFilter.setText(""); //$NON-NLS-1$
1185                                 }
1186
1187                                 txtFilterKeyPressEvent(arg0);
1188                         }
1189
1190                         @Override
1191                         public void keyPressed(KeyEvent arg0) {
1192
1193                         }
1194                 });
1195
1196                 fd_lstAccounts.left = new FormAttachment(0, 10);
1197                 fd_lstAccounts.right = new FormAttachment(100, -10);
1198
1199                 lstAccounts.getControl().setLayoutData(fd_lstAccounts);
1200                 lstAccounts.addDoubleClickListener( new IDoubleClickListener() {
1201
1202                         @Override
1203                         public void doubleClick(DoubleClickEvent arg0) {
1204                                 StructuredSelection selection = (StructuredSelection) arg0.getSelection();
1205                                 if( !selection.isEmpty() )
1206                                 {
1207                                         Account acc = (Account)selection.getFirstElement();
1208                                         showTrigDialog(acc);
1209                                 }
1210                         }
1211
1212
1213                 });
1214
1215                 lstAccounts.addSelectionChangedListener( new ISelectionChangedListener() {
1216
1217                         @Override
1218                         public void selectionChanged(SelectionChangedEvent arg0) {
1219                                 StructuredSelection selection = (StructuredSelection) arg0.getSelection();
1220                                 if( !selection.isEmpty() )
1221                                 {
1222                                         btnOpenAccount.setEnabled(true);
1223
1224                                         //Remove any listeners
1225                                         for( Listener s :btnOpenAccount.getListeners(SWT.Selection) )
1226                                         {
1227                                                 btnOpenAccount.removeListener(SWT.Selection, s);
1228                                         }
1229
1230                                         btnOpenAccount.addSelectionListener( new SelectionListener() {
1231
1232                                                 @Override
1233                                                 public void widgetSelected(SelectionEvent arg0) {
1234                                                         StructuredSelection selection = (StructuredSelection) lstAccounts.getSelection();
1235                                                         Account acc = (Account)selection.getFirstElement();
1236                                                         showTrigDialog(acc);
1237                                                 }
1238
1239                                                 @Override
1240                                                 public void widgetDefaultSelected(SelectionEvent arg0) {
1241                                                         // TODO Auto-generated method stub
1242                                                 }
1243                                         });
1244                                 }
1245                         }
1246                 });
1247
1248
1249                 lstAccountsControl.addKeyListener( new KeyListener() {
1250                         @Override
1251                         public void keyReleased(KeyEvent arg0) {
1252                         }
1253
1254                         @Override
1255                         public void keyPressed(KeyEvent arg0) {
1256                                 if( arg0.keyCode > 31 && arg0.keyCode < 126 && (arg0.stateMask&SWT.CTRL)!=SWT.CTRL )
1257                                 {
1258                                         txtFilter.setFocus();
1259                                         txtFilter.setText( ""+(char)arg0.keyCode ); //$NON-NLS-1$
1260                                         txtFilterKeyPressEvent(arg0);
1261                                         txtFilter.setSelection(1);
1262                                 } else if( arg0.keyCode == SWT.ARROW_UP)
1263                                 {
1264                                         //If selectionIndex is already 0, that means that the previous event caused that, so this time, it's changing nothing
1265                                         //and we can use it to wrap
1266                                         if( lstAccountsControl.getSelectionIndex() == 0)
1267                                         {
1268                                                 lstAccountsControl.setSelection( lstAccountsControl.getItemCount()-1 );
1269                                                 arg0.doit=false;
1270                                         }
1271                                 } else if( arg0.keyCode == SWT.ARROW_DOWN)
1272                                 {
1273                                         if( lstAccountsControl.getSelectionIndex() == lstAccountsControl.getItemCount()-1 )
1274                                         {
1275                                                 lstAccountsControl.setSelection(0);
1276                                                 arg0.doit=false;
1277                                         }
1278                                 }
1279                         }
1280                 });
1281
1282                 lstAccountsControl.addFocusListener( new FocusListener() {
1283
1284                         @Override
1285                         public void focusLost(FocusEvent arg0) {
1286
1287                         }
1288
1289                         @Override
1290                         public void focusGained(FocusEvent arg0) {
1291                                 if( lstAccountsControl.getItemCount() == 0 )
1292                                 {
1293                                         updateFilteredList(FkManager.getInstance().getList());
1294                                 }
1295
1296                         }
1297                 });
1298
1299                 cmpAccounts.setTabList(new Control[]{txtFilter,lstAccountsControl, btnOpenAccount, btnNewAccount});
1300         }
1301
1302         protected void txtFilterKeyPressEvent(KeyEvent arg0) {
1303                 Vector<Account> res = null;
1304
1305                 if( txtFilter.getText().length() == 0 )
1306                 {
1307                         res=FkManager.getInstance().getList();
1308                         txtFilter.setBackground( defaultBgColor );
1309                 } else {
1310                         res = FkManager.getInstance().getList(txtFilter.getText());
1311                         if( res.size() < 1 )
1312                         {
1313                                 txtFilter.setBackground( redColor );
1314                         } else if( res.size() == 1 )
1315                         {
1316                                 txtFilter.setBackground( greenColor );
1317                                 if( arg0.character== SWT.CR)
1318                                 {
1319                                         showTrigDialog(res.get(0));
1320                                 }
1321                         } else {
1322                                 txtFilter.setBackground( defaultBgColor );
1323                         }
1324                 }
1325
1326
1327                 if( res != null )
1328                 {
1329                         updateFilteredList( res );
1330                         if( res.size() > 0 )
1331                         {
1332                                 if( arg0.keyCode == SWT.ARROW_UP )
1333                                 {
1334                                         lstAccountsControl.setFocus();
1335                                         lstAccountsControl.setSelection( res.size()-1 );
1336                                 }
1337
1338                                 if( arg0.keyCode == SWT.ARROW_DOWN )
1339                                 {
1340                                         lstAccountsControl.setFocus();
1341                                         lstAccountsControl.setSelection( 0 );
1342                                 }
1343                         }
1344                 }
1345         }
1346
1347         private void addSettingsTab()
1348         {
1349                 tbtmSettings = new TabItem(tabFolder, SWT.NONE);
1350                 tbtmSettings.setText(Messages.MainWin_tbtmSettings_text);
1351
1352                 cmpSettings = new Composite(tabFolder, SWT.BORDER);
1353                 tbtmSettings.setControl(cmpSettings);
1354                 cmpSettings.setLayout(new FormLayout());
1355
1356                 chkAutoHide = new Button(cmpSettings, SWT.CHECK);
1357                 chkAutoHide.setText(Messages.MainWin_6);
1358                 chkAutoHide.setSelection( prefs.getBoolean( PREF_AUTOHIDE, false ) );
1359                 FormData fd_chkAutoHide = new FormData();
1360                 fd_chkAutoHide.top = new FormAttachment(0, 10);
1361                 fd_chkAutoHide.left = new FormAttachment(0, 10);
1362                 chkAutoHide.setLayoutData(fd_chkAutoHide);
1363                 chkAutoHide.addSelectionListener( new SelectionAdapter() {
1364                         public void widgetSelected(SelectionEvent e) {
1365                                 prefs.putBoolean(PREF_AUTOHIDE, chkAutoHide.getSelection() );
1366                         }
1367                 });
1368
1369                 chkSortByAccountId = new Button(cmpSettings, SWT.CHECK);
1370                 fd_chkAutoHide.right = new FormAttachment(chkSortByAccountId, 0, SWT.RIGHT);
1371                 chkSortByAccountId.setText(Messages.MainWin_9);
1372                 chkSortByAccountId.setSelection( prefs.getBoolean( PREF_SORT_BY_ID_KEY, false) );
1373                 FormData fd_btnSortByAccountId = new FormData();
1374                 fd_btnSortByAccountId.top = new FormAttachment(chkAutoHide, 6);
1375                 fd_btnSortByAccountId.left = new FormAttachment(0, 10);
1376                 fd_btnSortByAccountId.right = new FormAttachment(100, -10);
1377                 chkSortByAccountId.setLayoutData(fd_btnSortByAccountId);
1378                 chkSortByAccountId.addSelectionListener( new SelectionAdapter() {
1379                         public void widgetSelected(SelectionEvent e) {
1380                                 prefs.putBoolean( PREF_SORT_BY_ID_KEY, chkSortByAccountId.getSelection() );
1381                                 FkManager.getInstance().sortById( chkSortByAccountId.getSelection() );
1382                                 updateAccountList();
1383                         }
1384                 });
1385
1386                 chkShowAccountId = new Button(cmpSettings, SWT.CHECK);
1387                 FormData fd_chkShowAccountId = new FormData();
1388                 fd_chkShowAccountId.left = new FormAttachment(0, 10);
1389                 fd_chkShowAccountId.right = new FormAttachment(100, -10);
1390                 fd_chkShowAccountId.top = new FormAttachment(chkSortByAccountId, 6);
1391                 chkShowAccountId.setLayoutData(fd_chkShowAccountId);
1392                 chkShowAccountId.setText(Messages.MainWin_btnShowAccountId_text);
1393                 chkShowAccountId.setSelection( prefs.getBoolean(PREF_SHOW_ACCOUNT_ID_IN_NAME_KEY, false) );
1394                 chkShowAccountId.addSelectionListener( new SelectionAdapter() {
1395                         public void widgetSelected(SelectionEvent e) {
1396                                 prefs.putBoolean( PREF_SHOW_ACCOUNT_ID_IN_NAME_KEY, chkShowAccountId.getSelection() );
1397                                 updateAccountList();
1398                         }
1399                 });
1400
1401                 chkCheckForUpdates = new Button(cmpSettings, SWT.CHECK);
1402                 FormData fd_chkCheckForUpdates = new FormData();
1403                 fd_chkCheckForUpdates.left = new FormAttachment(0, 10);
1404                 fd_chkCheckForUpdates.right = new FormAttachment(100, -10);
1405                 fd_chkCheckForUpdates.top = new FormAttachment(chkShowAccountId, 6);
1406                 chkCheckForUpdates.setLayoutData(fd_chkCheckForUpdates);
1407                 chkCheckForUpdates.setText(Messages.MainWin_btnCheckForUpdates_text);
1408                 chkCheckForUpdates.setSelection( prefs.getBoolean( PREF_ALLOW_UPDATE_CHECK, true) );
1409                 chkCheckForUpdates.addSelectionListener( new SelectionAdapter() {
1410                         public void widgetSelected(SelectionEvent e) {
1411                                 prefs.putBoolean( PREF_ALLOW_UPDATE_CHECK, chkCheckForUpdates.getSelection() );
1412                                 checkForUpdates();
1413                         }
1414                 });
1415
1416                 btnShowaccountsReady = new Button(cmpSettings, SWT.CHECK);
1417                 btnShowaccountsReady.setSelection( prefs.getBoolean( PREF_SHOW_ACCOUNTS_READY_NOTICE, true) );
1418                 FormData fd_btnShowaccountsReady = new FormData();
1419                 fd_btnShowaccountsReady.left = new FormAttachment(0, 10);
1420                 fd_btnShowaccountsReady.right = new FormAttachment(100, -10);
1421                 fd_btnShowaccountsReady.top = new FormAttachment(chkCheckForUpdates, 6);
1422                 btnShowaccountsReady.setLayoutData(fd_btnShowaccountsReady);
1423
1424                 btnShowaccountsReady.setText(Messages.MainWin_btnShowaccountsReady_text);
1425                 btnShowaccountsReady.addSelectionListener( new SelectionAdapter() {
1426                 public void widgetSelected(SelectionEvent e) {
1427                                 prefs.putBoolean( PREF_SHOW_ACCOUNTS_READY_NOTICE, btnShowaccountsReady.getSelection() );
1428                         }
1429                 });
1430
1431                 Button btnShowSystrayName = new Button( cmpSettings, SWT.CHECK );
1432                 btnShowSystrayName.setSelection( prefs.getBoolean( PREF_SHOW_SYSTRAY_NAME,  true) );
1433                 FormData fd_btnShowSystrayName = new FormData();
1434                 fd_btnShowSystrayName.left = new FormAttachment(0, 10);
1435                 fd_btnShowSystrayName.right = new FormAttachment(100, -10);
1436                 fd_btnShowSystrayName.top = new FormAttachment(btnShowaccountsReady, 6);
1437                 btnShowSystrayName.setLayoutData(fd_btnShowSystrayName);
1438                 btnShowSystrayName.setText( Messages.MainWin_14 );
1439                 btnShowSystrayName.addSelectionListener( new SelectionAdapter() {
1440                         public void widgetSelected(SelectionEvent e) {
1441                                 Button b = (Button)e.widget;
1442                                 prefs.putBoolean( PREF_SHOW_SYSTRAY_NAME, b.getSelection() );
1443                                 setSystrayIconTip(null);
1444                         }
1445                 });
1446
1447                 btnHideToTrayOnClose = new Button(cmpSettings, SWT.CHECK);
1448                 btnHideToTrayOnClose.setSelection( prefs.getBoolean( PREF_HIDE_ON_CLOSE, true) );
1449                 btnHideToTrayOnClose.addSelectionListener(new SelectionAdapter() {
1450                         @Override
1451                         public void widgetSelected(SelectionEvent e) {
1452                                 prefs.putBoolean( PREF_HIDE_ON_CLOSE, btnHideToTrayOnClose.getSelection() );
1453                         }
1454                 });
1455                 btnHideToTrayOnClose.setToolTipText(Messages.MainWin_btnHideToTrayOnClose_toolTipText);
1456                 FormData fd_btnHideToTrayOnClose = new FormData();
1457                 fd_btnHideToTrayOnClose.top = new FormAttachment(btnShowSystrayName, 6);
1458                 fd_btnHideToTrayOnClose.right = new FormAttachment(0, 695);
1459                 fd_btnHideToTrayOnClose.left = new FormAttachment(0, 10);
1460                 btnHideToTrayOnClose.setLayoutData(fd_btnHideToTrayOnClose);
1461                 btnHideToTrayOnClose.setText(Messages.MainWin_btnCheckButton_text);
1462
1463         }
1464
1465         private void showTrigDialog(Account acc) {
1466                 Account selectedAccount = acc;
1467                 TriggerDialog diag = new TriggerDialog(shell, shell.getStyle(), acc,
1468                                 mySelf);
1469
1470                 shell.setEnabled(false);
1471                 diag.open();
1472
1473                 // Check if the account still exists
1474                 Boolean deleted = true;
1475                 for (Account a : FkManager.getInstance().getList()) {
1476                         if (a.equals(selectedAccount)) {
1477                                 deleted = false;
1478                                 break;
1479                         }
1480                 }
1481
1482                 if (deleted) {
1483                         btnOpenAccount.setEnabled(false);
1484                 }
1485
1486                 txtFilter.setFocus();
1487                 shell.setEnabled(true);
1488         }
1489
1490         @Override
1491         public void updateCheckFinished(UpdateResultEvent event) {
1492                 updateCheckThread=null;
1493                 switch(event.result)
1494                 {
1495                 case CHECK_FAILED:
1496                         System.out.println("Trouble checking for updates."); //$NON-NLS-1$
1497                         break;
1498                 case NO_UPDATE:
1499                         System.out.println("No update avaiable at this time."); //$NON-NLS-1$
1500                         break;
1501                 case UPDATE_AVAILABLE:
1502                         String title =Messages.MainWin_52+event.version+Messages.MainWin_53;
1503                         String text = Messages.MainWin_54+event.message;
1504                         log(title);
1505                         log(text);
1506
1507                         MessageBox dialog = new MessageBox(shell, SWT.ICON_INFORMATION |SWT.YES | SWT.NO);
1508                         dialog.setText(title);
1509                         dialog.setMessage(text+"\n\n\n"+Messages.MainWin_13); //$NON-NLS-1$
1510                         int res = dialog.open();
1511
1512                         if( res == SWT.YES )
1513                         {
1514                                 if(Desktop.isDesktopSupported())
1515                                 {
1516                                         try {
1517                                                 URI uri = new URI("http://finalkey.net/"); //$NON-NLS-1$
1518                                                 log(Messages.MainWin_16+uri.toString());
1519                                                 //FIXME: For whichever reason, this causes busy-cursor on the application, even though ui works fine.
1520                                                 Desktop.getDesktop().browse(uri);
1521                                                 log(Messages.MainWin_17);
1522                                         } catch (Exception e) {
1523                                                 log(Messages.MainWin_20);
1524                                                 log(Messages.MainWin_21);
1525                                                 log(e.getLocalizedMessage());
1526                                         }
1527                                 }
1528                         } else {
1529                                 log(Messages.MainWin_11);
1530                         }
1531
1532                         break;
1533                 }
1534
1535         }
1536 }