Changed List to ListViewer.
[FinalKeyGui.git] / src / fkgui / MainWin.java
1 package fkgui;
2
3
4 import  java.util.prefs.*;
5 import java.awt.*;
6 import java.awt.event.ActionEvent;
7 import java.awt.event.ActionListener;
8
9 import javax.swing.UIManager;
10 import javax.swing.UnsupportedLookAndFeelException;
11
12 import org.eclipse.jface.viewers.ISelectionChangedListener;
13 import org.eclipse.jface.viewers.ListViewer;
14 import org.eclipse.jface.viewers.SelectionChangedEvent;
15 import org.eclipse.jface.viewers.StructuredSelection;
16 import org.eclipse.swt.widgets.Display;
17 import org.eclipse.swt.widgets.MessageBox;
18 import org.eclipse.swt.widgets.Shell;
19 import org.eclipse.swt.widgets.Button;
20 import org.eclipse.swt.SWT;
21 import org.eclipse.swt.events.SelectionAdapter;
22 import org.eclipse.swt.events.SelectionEvent;
23 import org.eclipse.swt.events.ShellEvent;
24 import org.eclipse.swt.events.ShellListener;
25 import org.eclipse.swt.widgets.Text;
26 import org.eclipse.swt.widgets.Label;
27 import org.eclipse.swt.widgets.Control;
28 import org.eclipse.wb.swt.SWTResourceManager;
29
30 import fkgui.FkManager.Account;
31 import fkgui.SerialWorker.SerialState;
32 import fkgui.UpdateChecker.AutoUpdaterResultListener;
33
34 import org.eclipse.swt.widgets.TabFolder;
35 import org.eclipse.swt.widgets.TabItem;
36 import org.eclipse.swt.widgets.Composite;
37 import org.eclipse.swt.layout.FormLayout;
38 import org.eclipse.swt.layout.FormData;
39 import org.eclipse.swt.layout.FormAttachment;
40
41
42 public class MainWin implements ConsoleMsg, AutoUpdaterResultListener {
43
44         protected Shell shell;
45         private Text txtPsw;
46         public TrayIcon trayIcon;
47         public PopupMenu popup;
48         public MenuItem showMain;
49         public MenuItem hideMain;
50
51         public Text txtLog;
52         public Button btnConnect;
53         public Button chkAutoHide;
54         public Label lblPort;
55         public Label lblPassword;
56         
57         public Animation animation;
58         
59         public TabFolder tabFolder;
60
61         private Text txtDev;
62         Preferences prefs;
63         MainWin mySelf;
64         private SerialState lastState = SerialState.Disconnected;
65         
66         SerialWorker fkSerial;
67         private boolean sysTrayIconVisible;
68
69         
70         static final String PREF_PORT ="lastUsedPortPref";
71         static final String DEFAULT_DEVICE = "/dev/FinalKey";
72         static final String PREF_AUTOHIDE = "hideMainWinAfterConnect";
73         public Composite cmpConnect;
74         private Composite cmpAccounts;
75         ListViewer lstAccounts;
76  
77         
78         /**
79          * Launch the application.
80          * @param args
81          */
82         public static void main(String[] args) {
83
84                 try {
85                         MainWin window = new MainWin();
86                         window.open();
87                 } catch (Exception e) {
88                         e.printStackTrace();
89                 }
90                 
91         }
92
93         /**
94          * Open the window.
95          */
96         public void open() {
97                 Display display = Display.getDefault();
98                 createContents();
99                 shell.open();
100                 shell.layout();
101                 createSysTrayIcon();
102                 serialEvent(SerialState.Disconnected);
103                 new Thread(new UpdateChecker(this)).start();
104
105                 while (!shell.isDisposed()) {
106                         if (!display.readAndDispatch()) {
107                                 display.sleep();                                
108                         }
109                 }
110         }
111         
112         public void log( String str )
113         {
114                 txtLog.append(str+"\n");
115                 if( tabFolder.getSelectionIndex() == 0 )
116                 {
117                         txtLog.redraw();
118                         shell.redraw();
119                 }
120                 System.out.println(str);
121
122         }
123
124         /**
125          * Create a systemTray icon
126          */
127         private void createSysTrayIcon()
128         {
129                 sysTrayIconVisible=true;
130         //Check the SystemTray is supported
131         if (!SystemTray.isSupported()) {
132             log("SystemTray is not supported, app is useless");
133             return;
134         }
135         
136         try {
137                         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
138                 } catch (ClassNotFoundException e1) {
139                         // TODO Auto-generated catch block
140                         e1.printStackTrace();
141                 } catch (InstantiationException e1) {
142                         // TODO Auto-generated catch block
143                         e1.printStackTrace();
144                 } catch (IllegalAccessException e1) {
145                         // TODO Auto-generated catch block
146                         e1.printStackTrace();
147                 } catch (UnsupportedLookAndFeelException e1) {
148                         // TODO Auto-generated catch block
149                         e1.printStackTrace();
150                 }
151
152         popup = new PopupMenu();
153         trayIcon =
154                 new TrayIcon(Toolkit.getDefaultToolkit().createImage(getClass().getResource("finalkey.png")));
155         trayIcon.setToolTip("The Final Key - Hardware password manager");
156         trayIcon.setImageAutoSize(true);
157         final SystemTray tray = SystemTray.getSystemTray();
158        
159         // Create a pop-up menu components
160         showMain = new MenuItem("Show FinalKey");
161         hideMain = new MenuItem("Hide FinalKey");
162
163         showMain.addActionListener(new ActionListener() {
164                         @Override
165                         public void actionPerformed(ActionEvent e) {
166                                 Display.getDefault().syncExec( new Runnable(){
167                                         
168                                         public void run()
169                                         {
170                                                 showFromTray();
171                                         }
172                                 } );
173                         }
174                                 
175                 });
176         
177         hideMain.addActionListener(new ActionListener() {
178                         @Override
179                         public void actionPerformed(ActionEvent e) {
180                                 Display.getDefault().syncExec( new Runnable(){
181                                         
182                                         public void run()
183                                         {
184                                                 hideToTray();
185                                         }
186                                 } );
187                         }
188                                 
189                 });
190
191         clearSystray();
192
193
194         trayIcon.setPopupMenu(popup);
195        
196         try {
197             tray.add(trayIcon);
198         } catch (AWTException e) {
199                 log("TrayIcon could not be added.");
200         }       
201         
202         }
203         
204         private void hideToTray()
205         {
206                 popup.remove(0);
207                 popup.insert(showMain, 0);
208                 shell.setVisible(false);
209         }
210         
211         private void showFromTray()
212         {
213                 popup.remove(0);
214                 popup.insert(hideMain, 0);
215                 shell.setVisible(true);
216                 shell.forceActive();
217         }
218         
219         private void destroySysTrayIcon()
220         {
221                 sysTrayIconVisible=false;
222                 SystemTray.getSystemTray().remove(trayIcon);
223         }
224         
225         private void clearSystray() {
226                         popup.removeAll();
227                 //Add components to pop-up menu
228                         if(shell.isVisible()==true)
229                         {
230                                 popup.add(hideMain);
231                         } else {
232                                 popup.add(showMain);
233                         }
234                 popup.addSeparator();
235         }
236
237         public void shutDownApp()
238         {
239                 if(fkSerial != null)
240                 {
241                         fkSerial.disconnect();
242                 }
243                 if(sysTrayIconVisible == true)
244                 {
245                         destroySysTrayIcon();
246                 }
247                 System.exit(0);
248         }
249         
250         /**
251          * Create contents of the window.
252          */
253         protected void createContents() {
254                 shell = new Shell();
255                 shell.setImage(SWTResourceManager.getImage(MainWin.class, "/fkgui/finalkey.png"));
256                 shell.setSize(711, 655);
257                 shell.setText("Final Key (Not connected)");
258
259                 
260                 prefs = Preferences.userNodeForPackage(this.getClass());
261                 
262
263                 mySelf = this;
264                 shell.setLayout(new FormLayout());
265                 
266                 tabFolder = new TabFolder(shell, SWT.NONE);
267                 FormData fd_tabFolder = new FormData();
268                 fd_tabFolder.bottom = new FormAttachment(0, 627);
269                 fd_tabFolder.right = new FormAttachment(0, 709);
270                 fd_tabFolder.top = new FormAttachment(0);
271                 fd_tabFolder.left = new FormAttachment(0);
272                 tabFolder.setLayoutData(fd_tabFolder);
273                 tabFolder.setBackground(SWTResourceManager.getColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));
274                 
275                 TabItem tbtmConnection = new TabItem(tabFolder, SWT.NONE);
276                 tbtmConnection.setText("Connection");
277                 
278                 cmpConnect = new Composite(tabFolder, SWT.BORDER);
279                 tbtmConnection.setControl(cmpConnect);
280                 cmpConnect.setLayout(new FormLayout());
281                 
282
283                 btnConnect = new Button(cmpConnect, SWT.CENTER);
284                 btnConnect.setImage(SWTResourceManager.getImage("/home/dusted/Downloads/lightning.png"));
285                 FormData fd_btnConnect = new FormData();
286                 fd_btnConnect.left = new FormAttachment(100, -125);
287                 fd_btnConnect.right = new FormAttachment(100, -10);
288                 btnConnect.setLayoutData(fd_btnConnect);
289
290                 btnConnect.addSelectionListener(new SelectionAdapter() {
291                         public void widgetSelected(SelectionEvent e) {
292                                 
293                                 if( fkSerial!=null && fkSerial.state == SerialState.Connected )
294                                 {
295                                         fkSerial.disconnect();
296                                 } else {
297                                         
298                                         prefs.putBoolean(PREF_AUTOHIDE, chkAutoHide.getSelection() );
299
300                                         fkSerial = new SerialWorker(mySelf);
301                                         prefs.put(PREF_PORT, txtDev.getText() );
302                                         fkSerial.connect(txtDev.getText(),txtPsw.getText());
303                                         txtPsw.setText("");
304                                 }
305                         }
306                 });
307                 btnConnect.setText("Connect");
308                 
309                 txtPsw = new Text(cmpConnect, SWT.BORDER | SWT.PASSWORD);
310                 fd_btnConnect.bottom = new FormAttachment(txtPsw, 0, SWT.BOTTOM);
311                 FormData fd_txtPsw = new FormData();
312                 fd_txtPsw.bottom = new FormAttachment(0, 52);
313                 fd_txtPsw.right = new FormAttachment(0, 501);
314                 fd_txtPsw.top = new FormAttachment(0, 29);
315                 fd_txtPsw.left = new FormAttachment(0, 102);
316                 txtPsw.setLayoutData(fd_txtPsw);
317                 
318                 txtLog = new Text(cmpConnect, SWT.BORDER | SWT.V_SCROLL | SWT.MULTI);
319                 FormData fd_txtLog = new FormData();
320                 fd_txtLog.left = new FormAttachment(0, 10);
321                 fd_txtLog.right = new FormAttachment(100, -10);
322                 fd_txtLog.bottom = new FormAttachment(100, -10);
323                 fd_txtLog.top = new FormAttachment(0, 58);
324                 txtLog.setLayoutData(fd_txtLog);
325                 txtLog.setEditable(false);
326                 
327                 lblPort = new Label(cmpConnect, SWT.NONE);
328                 fd_btnConnect.top = new FormAttachment(lblPort, 0, SWT.TOP);
329                 FormData fd_lblPort = new FormData();
330                 fd_lblPort.right = new FormAttachment(0, 86);
331                 fd_lblPort.top = new FormAttachment(0);
332                 fd_lblPort.left = new FormAttachment(0, 10);
333                 lblPort.setLayoutData(fd_lblPort);
334                 lblPort.setText("Port");
335                 
336                 txtDev = new Text(cmpConnect, SWT.BORDER);
337                 FormData fd_txtDev = new FormData();
338                 fd_txtDev.bottom = new FormAttachment(0, 23);
339                 fd_txtDev.right = new FormAttachment(0, 256);
340                 fd_txtDev.top = new FormAttachment(0);
341                 fd_txtDev.left = new FormAttachment(0, 102);
342                 txtDev.setLayoutData(fd_txtDev);
343                 txtDev.setFont(SWTResourceManager.getFont("Cantarell", 9, SWT.NORMAL));
344                 txtDev.setText( prefs.get(PREF_PORT, DEFAULT_DEVICE));
345                 lblPassword = new Label(cmpConnect, SWT.NONE);
346                 FormData fd_lblPassword = new FormData();
347                 fd_lblPassword.right = new FormAttachment(0, 95);
348                 fd_lblPassword.top = new FormAttachment(0, 29);
349                 fd_lblPassword.left = new FormAttachment(0, 10);
350                 lblPassword.setLayoutData(fd_lblPassword);
351                 lblPassword.setText("Password");
352                 
353                 chkAutoHide = new Button(cmpConnect, SWT.CHECK);
354                 FormData fd_chkAutoHide = new FormData();
355                 fd_chkAutoHide.right = new FormAttachment(0, 501);
356                 fd_chkAutoHide.top = new FormAttachment(0);
357                 fd_chkAutoHide.left = new FormAttachment(0, 262);
358                 chkAutoHide.setLayoutData(fd_chkAutoHide);
359                 chkAutoHide.setText("Hide after connection");
360                 
361                 chkAutoHide.setSelection( prefs.getBoolean(PREF_AUTOHIDE, false)) ;
362                 
363                 animation = new Animation(cmpConnect, SWT.NONE, 4);
364
365                 FormData fd_animation = new FormData();
366                 fd_animation.right = new FormAttachment(0, 86);
367                 fd_animation.top = new FormAttachment(0);
368                 fd_animation.left = new FormAttachment(0, 10);          
369                 
370                 animation.setLayoutData(fd_animation);
371
372
373                 
374                 
375
376                 
377                 animation.setVisible(false);
378                 animation.addFrame( SWTResourceManager.getImage("/home/dusted/Downloads/finalkey1.png") );
379                 animation.addFrame( SWTResourceManager.getImage("/home/dusted/Downloads/finalkey2.png") );
380                 animation.setPlaying(false);
381                 cmpConnect.setTabList(new Control[]{txtPsw, btnConnect});
382                 
383         
384                 
385                 log("Type your password and press connect.\n----------\n");
386
387
388                 shell.addShellListener( new ShellListener() {
389                         
390                         public void shellIconified(ShellEvent e) {
391
392                         }
393
394                         public void shellDeiconified(ShellEvent e) {
395                                 // TODO Auto-generated method stub
396                                 
397                         }
398                         
399                         public void shellDeactivated(ShellEvent e) {
400                                 // TODO Auto-generated method stub
401                                 
402                         }
403                         
404                         public void shellClosed(ShellEvent e) {
405                                 shutDownApp();
406                         }
407                         
408                         public void shellActivated(ShellEvent e) {
409                                 // TODO Auto-generated method stub
410                                 
411                         }
412                 } );
413                 
414
415
416         }
417
418
419         @Override
420         public void serialEvent(SerialState state) {
421                 switch(state)
422                 {
423                 case Connected:
424                         shell.setText("Final Key (Connected)");
425                         
426                         animation.setVisible(false);
427                         animation.setPlaying(false);
428
429
430                         btnConnect.setText("Disconnect");
431                         btnConnect.setVisible(true);
432                         
433                         //Should we hide?
434                         if( prefs.getBoolean(PREF_AUTOHIDE, false) == true)
435                         {
436                                 hideToTray();
437                         }
438                         
439                         addAccountsTab();
440                         
441                         
442                         tabFolder.setSelection(1);
443                         
444                         for( FkManager.Account a : FkManager.getInstance().getList() )
445                         {
446                                 lstAccounts.add( a );
447                                                                 
448                                 Menu menu = new Menu(a.name+" ["+a.num+"]");
449                                 MenuItem both = new MenuItem("User + Pass");
450                                 MenuItem usr = new MenuItem("User");
451                                 MenuItem psw = new MenuItem("Pass");
452                                 menu.add(both);
453                                 menu.add(usr);
454                                 menu.add(psw);
455
456
457                                 both.addActionListener(FkManager.getInstance());
458                                 both.setActionCommand( "%"+a.num );
459
460
461
462                                 psw.addActionListener(FkManager.getInstance()); 
463                                 psw.setActionCommand( "p"+a.num);
464
465
466                                 usr.addActionListener(FkManager.getInstance()); 
467                                 usr.setActionCommand( "u"+a.num );
468
469                                 popup.add(menu);
470                                 
471                                 
472                         }
473                         
474                         
475                         int numAccounts=FkManager.getInstance().getList().size();
476                         if( numAccounts>0 )
477                         {
478                                 trayIcon.displayMessage("FinalKey", numAccounts + " account"+(( numAccounts >1)?"s":"")+" ready.", 
479                                     TrayIcon.MessageType.INFO);
480                         }
481
482                         
483                         log("* Connected *");
484                         break;
485                 case Connecting:
486                         shell.setText("Final Key (Connecting...)");
487                         animation.setVisible(true);
488                         animation.setPlaying(true);
489
490                         txtPsw.setVisible(false);
491                         txtDev.setVisible(false);
492                         btnConnect.setVisible(false);
493                         lblPort.setVisible(false);
494                         lblPassword.setVisible(false);
495                         chkAutoHide.setVisible(false);
496                         break;
497                 case Disconnected:
498                         fkSerial=null;
499                         animation.setVisible(false);
500                         animation.setPlaying(false);
501
502                         remAccountsTab();
503                         
504                         tabFolder.setSelection(0);
505
506                         shell.setText("Final Key (Not connected)");
507                         txtPsw.setVisible(true);
508                         txtDev.setVisible(true);
509                         btnConnect.setText("Connect");
510                         btnConnect.setVisible(true);
511                         lblPort.setVisible(true);
512                         lblPassword.setVisible(true);
513                         chkAutoHide.setVisible(true);
514                         clearSystray();
515                         if(lastState != state)
516                         {
517                                 log("* Disconnected *");
518                         }
519                         break;
520                 
521                 case Working:
522                         animation.setPlaying(false);
523                         animation.setVisible(false);
524                         break;
525                         
526                 default:
527                         break;
528                 }
529                 lastState=state;
530                 cmpConnect.layout();
531         }
532
533         private void remAccountsTab() {
534                 if( tabFolder.getItemCount() > 1 )
535                 {
536                         tabFolder.getItem(1).dispose();
537                 }
538                 
539         }
540
541         private void addAccountsTab() {
542                 TabItem tbtmAccounts = new TabItem(tabFolder, SWT.NONE);
543                 tbtmAccounts.setText("Accounts");
544                 
545                 cmpAccounts = new Composite(tabFolder, SWT.BORDER);
546                 tbtmAccounts.setControl(cmpAccounts);
547                 cmpAccounts.setLayout(new FormLayout());
548                 
549                 Button btnNewAccoount = new Button(cmpAccounts, SWT.NONE);
550                 btnNewAccoount.setImage(SWTResourceManager.getImage("/home/dusted/Downloads/Button New-01.png"));
551                 btnNewAccoount.addSelectionListener(new SelectionAdapter() {
552                         @Override
553                         public void widgetSelected(SelectionEvent e) {
554                         }
555                 });
556                 FormData fd_btnNewAccoount = new FormData();
557                 fd_btnNewAccoount.left = new FormAttachment(0, 530);
558                 fd_btnNewAccoount.right = new FormAttachment(100, -10);
559                 fd_btnNewAccoount.bottom = new FormAttachment(100, -10);
560                 btnNewAccoount.setLayoutData(fd_btnNewAccoount);
561                 btnNewAccoount.setText("New Account");
562                 
563                 lstAccounts = new ListViewer(cmpAccounts, SWT.BORDER | SWT.V_SCROLL);
564                 FormData fd_lstAccounts = new FormData();
565                 fd_lstAccounts.bottom = new FormAttachment(btnNewAccoount, -6);
566                 fd_lstAccounts.top = new FormAttachment(0, 10);
567                 fd_lstAccounts.left = new FormAttachment(0, 10);
568                 fd_lstAccounts.right = new FormAttachment(100, -10);
569                 
570
571                 //lstAccounts.setLayoutData(fd_lstAccounts);
572                 lstAccounts.getControl().setLayoutData(fd_lstAccounts);
573                 
574                 lstAccounts.addSelectionChangedListener(new ISelectionChangedListener() {
575                         
576                         @Override
577                         public void selectionChanged(SelectionChangedEvent arg0) {
578
579                                 StructuredSelection selection = (StructuredSelection) arg0.getSelection();
580                                 if( !selection.isEmpty() )
581                                 {
582                                         Account acc = (Account)selection.getFirstElement();
583                                         TriggerDialog diag = new TriggerDialog(shell, shell.getStyle(), acc );
584
585                                         shell.setMinimized(true);
586                                         shell.setEnabled(false);
587                                         if( !((Boolean)diag.open()) )
588                                         {
589                                                 shell.setMinimized(false);
590                                         }
591                                         
592                                         shell.setEnabled(true);
593                                 } else {
594                                         System.out.println("Selected nothing.");
595                                 }                               
596                                 
597                                 
598                                 
599                         }
600                 });
601                                 
602         }
603
604
605         @Override
606         public void updateCheckFinished(AutoUpdaterResultEvent event) {
607                 switch(event.result)
608                 {
609                 case CHECK_FAILED:
610                         System.out.println("Trouble checking for updates.");
611                         break;
612                 case NO_UPDATE:
613                         System.out.println("No update avaiable at this time.");
614                         break;
615                 case UPDATE_AVAILABLE:
616                         MessageBox dialog = new MessageBox(shell, SWT.ICON_INFORMATION | SWT.OK);
617                         dialog.setText("FinalKey GUI Version "+event.version+" available.");
618                         dialog.setMessage("There's a new version of FinalKey GUI available.\nGo to http://cyberstalker.dk/finalkey/gui/ to download.\n\nNews:\n"+event.message);
619                         dialog.open();  
620                         break;
621                 }
622                 
623         }
624
625
626 }