0576351d580d917e0448fc11d811d3beedb2927e
[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 import java.beans.PropertyChangeEvent;
9 import java.beans.PropertyChangeListener;
10
11 import javax.swing.UIManager;
12 import javax.swing.UnsupportedLookAndFeelException;
13
14 import org.eclipse.swt.widgets.Display;
15 import org.eclipse.swt.widgets.Event;
16 import org.eclipse.swt.widgets.Listener;
17 import org.eclipse.swt.widgets.Shell;
18 import org.eclipse.swt.widgets.Button;
19 import org.eclipse.swt.SWT;
20 import org.eclipse.swt.events.ModifyEvent;
21 import org.eclipse.swt.events.ModifyListener;
22 import org.eclipse.swt.events.SelectionAdapter;
23 import org.eclipse.swt.events.SelectionEvent;
24 import org.eclipse.swt.events.SelectionListener;
25 import org.eclipse.swt.events.ShellEvent;
26 import org.eclipse.swt.events.ShellListener;
27 import org.eclipse.swt.widgets.Text;
28 import org.eclipse.swt.widgets.Label;
29 import org.eclipse.swt.widgets.Control;
30 import org.eclipse.wb.swt.SWTResourceManager;
31
32 import fkgui.SerialWorker.SerialState;
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.FillLayout;
38 import org.eclipse.swt.layout.GridLayout;
39 import org.eclipse.swt.layout.FormLayout;
40 import org.eclipse.swt.layout.FormData;
41 import org.eclipse.swt.layout.FormAttachment;
42 import org.eclipse.swt.widgets.List;
43
44 public class MainWin implements ConsoleMsg {
45
46         protected Shell shell;
47         private Text txtPsw;
48         public TrayIcon trayIcon;
49         public PopupMenu popup;
50         public MenuItem showMain;
51         public MenuItem hideMain;
52
53         public Text txtLog;
54         public Button btnConnect;
55         public Button chkAutoHide;
56         public Label lblPort;
57         public Label lblPassword;
58
59         private Text txtDev;
60         Preferences prefs;
61         MainWin mySelf;
62         private SerialState lastState = SerialState.Disconnected;
63         
64         SerialWorker fkSerial;
65         private boolean sysTrayIconVisible;
66
67         
68         static final String PREF_PORT ="lastUsedPortPref";
69         static final String DEFAULT_DEVICE = "/dev/FinalKey";
70         static final String PREF_AUTOHIDE = "hideMainWinAfterConnect";
71         public Composite cmpConnect;
72         private Composite composite;
73         private Composite cmpAccounts;
74         List lstAccounts;
75         private Text txtSearch;
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
104                 while (!shell.isDisposed()) {
105                         if (!display.readAndDispatch()) {
106                                 display.sleep();                                
107                         }
108                 }
109         }
110         
111         public void log( String str )
112         {
113                 txtLog.append(str+"\n");
114                 txtLog.redraw();
115                 shell.redraw();
116                 System.out.println(str);
117         }
118
119         /**
120          * Create a systemTray icon
121          */
122         private void createSysTrayIcon()
123         {
124                 sysTrayIconVisible=true;
125         //Check the SystemTray is supported
126         if (!SystemTray.isSupported()) {
127             log("SystemTray is not supported, app is useless");
128             return;
129         }
130         
131         try {
132                         UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
133                 } catch (ClassNotFoundException e1) {
134                         // TODO Auto-generated catch block
135                         e1.printStackTrace();
136                 } catch (InstantiationException e1) {
137                         // TODO Auto-generated catch block
138                         e1.printStackTrace();
139                 } catch (IllegalAccessException e1) {
140                         // TODO Auto-generated catch block
141                         e1.printStackTrace();
142                 } catch (UnsupportedLookAndFeelException e1) {
143                         // TODO Auto-generated catch block
144                         e1.printStackTrace();
145                 }
146
147         popup = new PopupMenu();
148         trayIcon =
149                 new TrayIcon(Toolkit.getDefaultToolkit().createImage(getClass().getResource("finalkey.png")));
150         trayIcon.setImageAutoSize(true);
151         final SystemTray tray = SystemTray.getSystemTray();
152        
153         // Create a pop-up menu components
154         showMain = new MenuItem("Show FinalKey");
155         hideMain = new MenuItem("Hide FinalKey");
156
157         showMain.addActionListener(new ActionListener() {
158                         @Override
159                         public void actionPerformed(ActionEvent e) {
160                                 Display.getDefault().syncExec( new Runnable(){
161                                         
162                                         public void run()
163                                         {
164                                                 showFromTray();
165                                         }
166                                 } );
167                         }
168                                 
169                 });
170         
171         hideMain.addActionListener(new ActionListener() {
172                         @Override
173                         public void actionPerformed(ActionEvent e) {
174                                 Display.getDefault().syncExec( new Runnable(){
175                                         
176                                         public void run()
177                                         {
178                                                 hideToTray();
179                                         }
180                                 } );
181                         }
182                                 
183                 });
184
185         clearSystray();
186
187
188         trayIcon.setPopupMenu(popup);
189        
190         try {
191             tray.add(trayIcon);
192         } catch (AWTException e) {
193                 log("TrayIcon could not be added.");
194         }       
195         
196         }
197         
198         private void hideToTray()
199         {
200                 popup.remove(0);
201                 popup.insert(showMain, 0);
202                 shell.setVisible(false);
203         }
204         
205         private void showFromTray()
206         {
207                 popup.remove(0);
208                 popup.insert(hideMain, 0);
209                 shell.setVisible(true);
210                 shell.forceActive();
211         }
212         
213         private void destroySysTrayIcon()
214         {
215                 sysTrayIconVisible=false;
216                 SystemTray.getSystemTray().remove(trayIcon);
217         }
218         
219         private void clearSystray() {
220                         popup.removeAll();
221                 //Add components to pop-up menu
222                         if(shell.isVisible()==true)
223                         {
224                                 popup.add(hideMain);
225                         } else {
226                                 popup.add(showMain);
227                         }
228                 popup.addSeparator();
229         }
230
231         public void shutDownApp()
232         {
233                 if(fkSerial != null)
234                 {
235                         fkSerial.disconnect();
236                 }
237                 if(sysTrayIconVisible == true)
238                 {
239                         destroySysTrayIcon();
240                 }
241                 System.exit(0);
242         }
243         
244         /**
245          * Create contents of the window.
246          */
247         protected void createContents() {
248                 shell = new Shell();
249                 shell.setImage(SWTResourceManager.getImage(MainWin.class, "/fkgui/finalkey.png"));
250                 shell.setSize(711, 655);
251                 shell.setText("Final Key (Not connected)");
252
253                 
254                 prefs = Preferences.userNodeForPackage(this.getClass());
255                 
256
257                 mySelf = this;
258                 shell.setLayout(new FillLayout(SWT.HORIZONTAL));
259                 
260                 TabFolder tabFolder = new TabFolder(shell, SWT.NONE);
261                 tabFolder.setBackground(SWTResourceManager.getColor(SWT.COLOR_WIDGET_LIGHT_SHADOW));
262                 
263                 TabItem tbtmConnection = new TabItem(tabFolder, SWT.NONE);
264                 tbtmConnection.setText("Connection");
265                 
266                 cmpConnect = new Composite(tabFolder, SWT.BORDER);
267                 tbtmConnection.setControl(cmpConnect);
268                 cmpConnect.setLayout(new FormLayout());
269                 
270
271                 btnConnect = new Button(cmpConnect, SWT.CENTER);
272                 FormData fd_btnConnect = new FormData();
273                 fd_btnConnect.right = new FormAttachment(100, -10);
274                 btnConnect.setLayoutData(fd_btnConnect);
275
276                 btnConnect.addSelectionListener(new SelectionAdapter() {
277                         public void widgetSelected(SelectionEvent e) {
278                                 
279                                 if( fkSerial!=null && fkSerial.state == SerialState.Connected )
280                                 {
281                                         fkSerial.disconnect();
282                                 } else {
283                                         
284                                         prefs.putBoolean(PREF_AUTOHIDE, chkAutoHide.getSelection() );
285
286                                         fkSerial = new SerialWorker(mySelf);
287                                         prefs.put(PREF_PORT, txtDev.getText() );
288                                         fkSerial.connect(txtDev.getText(),txtPsw.getText());
289                                         txtPsw.setText("");
290                                 }
291                         }
292                 });
293                 btnConnect.setText("Connect");
294                 
295                 txtPsw = new Text(cmpConnect, SWT.BORDER | SWT.PASSWORD);
296                 fd_btnConnect.bottom = new FormAttachment(txtPsw, 0, SWT.BOTTOM);
297                 FormData fd_txtPsw = new FormData();
298                 fd_txtPsw.bottom = new FormAttachment(0, 52);
299                 fd_txtPsw.right = new FormAttachment(0, 501);
300                 fd_txtPsw.top = new FormAttachment(0, 29);
301                 fd_txtPsw.left = new FormAttachment(0, 102);
302                 txtPsw.setLayoutData(fd_txtPsw);
303                 
304                 txtLog = new Text(cmpConnect, SWT.BORDER | SWT.V_SCROLL | SWT.MULTI);
305                 FormData fd_txtLog = new FormData();
306                 fd_txtLog.bottom = new FormAttachment(100, -10);
307                 fd_txtLog.right = new FormAttachment(btnConnect, 0, SWT.RIGHT);
308                 fd_txtLog.top = new FormAttachment(0, 58);
309                 fd_txtLog.left = new FormAttachment(0, 10);
310                 txtLog.setLayoutData(fd_txtLog);
311                 txtLog.setEditable(false);
312                 
313                 lblPort = new Label(cmpConnect, SWT.NONE);
314                 fd_btnConnect.top = new FormAttachment(lblPort, 0, SWT.TOP);
315                 FormData fd_lblPort = new FormData();
316                 fd_lblPort.right = new FormAttachment(0, 86);
317                 fd_lblPort.top = new FormAttachment(0);
318                 fd_lblPort.left = new FormAttachment(0, 10);
319                 lblPort.setLayoutData(fd_lblPort);
320                 lblPort.setText("Port");
321                 
322                 txtDev = new Text(cmpConnect, SWT.BORDER);
323                 FormData fd_txtDev = new FormData();
324                 fd_txtDev.bottom = new FormAttachment(0, 23);
325                 fd_txtDev.right = new FormAttachment(0, 256);
326                 fd_txtDev.top = new FormAttachment(0);
327                 fd_txtDev.left = new FormAttachment(0, 102);
328                 txtDev.setLayoutData(fd_txtDev);
329                 txtDev.setFont(SWTResourceManager.getFont("Cantarell", 9, SWT.NORMAL));
330                 txtDev.setText( prefs.get(PREF_PORT, DEFAULT_DEVICE));
331                 lblPassword = new Label(cmpConnect, SWT.NONE);
332                 FormData fd_lblPassword = new FormData();
333                 fd_lblPassword.right = new FormAttachment(0, 95);
334                 fd_lblPassword.top = new FormAttachment(0, 29);
335                 fd_lblPassword.left = new FormAttachment(0, 10);
336                 lblPassword.setLayoutData(fd_lblPassword);
337                 lblPassword.setText("Password");
338                 
339                 chkAutoHide = new Button(cmpConnect, SWT.CHECK);
340                 FormData fd_chkAutoHide = new FormData();
341                 fd_chkAutoHide.right = new FormAttachment(0, 501);
342                 fd_chkAutoHide.top = new FormAttachment(0);
343                 fd_chkAutoHide.left = new FormAttachment(0, 262);
344                 chkAutoHide.setLayoutData(fd_chkAutoHide);
345                 chkAutoHide.setText("Hide after connection");
346                 
347                 chkAutoHide.setSelection( prefs.getBoolean(PREF_AUTOHIDE, false)) ;
348                 
349                 cmpConnect.setTabList(new Control[]{txtPsw, btnConnect});
350                 
351                 
352                 TabItem tbtmOptions = new TabItem(tabFolder, SWT.NONE);
353                 tbtmOptions.setText("Options");
354                 
355                 composite = new Composite(tabFolder, SWT.BORDER);
356                 tbtmOptions.setControl(composite);
357                 
358                 TabItem tbtmAccounts = new TabItem(tabFolder, SWT.NONE);
359                 tbtmAccounts.setText("Accounts");
360                 
361                 cmpAccounts = new Composite(tabFolder, SWT.BORDER);
362                 tbtmAccounts.setControl(cmpAccounts);
363                 cmpAccounts.setLayout(new FormLayout());
364                 
365                 Button btnNewAccoount = new Button(cmpAccounts, SWT.NONE);
366                 FormData fd_btnNewAccoount = new FormData();
367                 fd_btnNewAccoount.top = new FormAttachment(0, 10);
368                 fd_btnNewAccoount.left = new FormAttachment(0, 10);
369                 btnNewAccoount.setLayoutData(fd_btnNewAccoount);
370                 btnNewAccoount.setText("New");
371                 
372                 Button btnEditAccount = new Button(cmpAccounts, SWT.NONE);
373                 FormData fd_btnEditAccount = new FormData();
374                 fd_btnEditAccount.top = new FormAttachment(0, 10);
375                 fd_btnEditAccount.left = new FormAttachment(0, 63);
376                 btnEditAccount.setLayoutData(fd_btnEditAccount);
377                 btnEditAccount.setText("Edit");
378                 
379                 Button btnDeleteAccount = new Button(cmpAccounts, SWT.NONE);
380                 FormData fd_btnDeleteAccount = new FormData();
381                 fd_btnDeleteAccount.top = new FormAttachment(btnNewAccoount, 0, SWT.TOP);
382                 btnDeleteAccount.setLayoutData(fd_btnDeleteAccount);
383                 btnDeleteAccount.setText("Delete");
384                 
385                 lstAccounts = new List(cmpAccounts, SWT.BORDER | SWT.V_SCROLL);
386                 fd_btnDeleteAccount.right = new FormAttachment(lstAccounts, 0, SWT.RIGHT);
387                 FormData fd_lstAccounts = new FormData();
388                 fd_lstAccounts.left = new FormAttachment(0, 10);
389                 fd_lstAccounts.bottom = new FormAttachment(100, -6);
390                 fd_lstAccounts.right = new FormAttachment(100, -10);
391                 fd_lstAccounts.top = new FormAttachment(btnNewAccoount, 6);
392
393                 lstAccounts.setLayoutData(fd_lstAccounts);
394                 
395                 lstAccounts.add("Facebook");
396                 lstAccounts.add("Twitter");
397                 lstAccounts.add("Krapbox Twitter");
398                 lstAccounts.add("Fjord");
399                 lstAccounts.add("Ordbogen");
400                 lstAccounts.add("Fisker");
401                 lstAccounts.add("KrapBox");
402                 lstAccounts.add("En to tre");
403                 lstAccounts.add("Item9");
404                 lstAccounts.add("Item0");
405                 lstAccounts.add("Itema");
406                 lstAccounts.add("Itemb");
407                 lstAccounts.add("Itemc");
408                 lstAccounts.add("Itemd");
409                 lstAccounts.add("Iteme");
410                 lstAccounts.add("Itemf");
411                 lstAccounts.add("Itemg");
412                 lstAccounts.add("Itemh");
413                 lstAccounts.add("Itemi");
414                 lstAccounts.add("Itemj");
415                 lstAccounts.add("Itemk");
416                 
417                 txtSearch = new Text(cmpAccounts, SWT.BORDER);
418                 txtSearch.setText("Search");
419                 FormData fd_txtSearch = new FormData();
420                 fd_txtSearch.right = new FormAttachment(btnDeleteAccount, -6);
421                 fd_txtSearch.bottom = new FormAttachment(lstAccounts, -6);
422                 fd_txtSearch.left = new FormAttachment(btnEditAccount, 6);
423                 txtSearch.setLayoutData(fd_txtSearch);
424                 
425                 lstAccounts.addListener(SWT.Selection, new Listener()
426                 {
427
428                         @Override
429                         public void handleEvent(Event event) {
430                                 System.out.println( "Selected Idx:"+lstAccounts.getSelectionIndex() );
431                                 //txtSearch.setText( lstAccounts.getItem(lstAccounts.getSelectionIndex() ) );
432                                 
433                         }
434                         
435                 });
436                 
437                 txtSearch.addModifyListener(new ModifyListener() {
438                         
439                         @Override
440                         public void modifyText(ModifyEvent e) {
441                                 if( txtSearch.getText().length()<1) return;
442
443                                 String lst[] = lstAccounts.getItems();
444                                 String wrds[] = txtSearch.getText().toLowerCase().split(" ");
445                                 int idx=0;
446                                 int scores[] = new int[lst.length];
447                                 for( String s : lst )
448                                 {
449                                         s = s.toLowerCase();
450                                         scores[idx]=0;
451                                         for(String w: wrds )
452                                         {
453                                                 if( s.contains(w) )
454                                                 {
455                                                         scores[idx]++;
456                                                         //System.out.println("Account: "+s+ " scores +1 for substring "+w);
457                                                 }
458                                         }
459                                         idx++;
460                                 }
461                                 
462                                 int top=0;
463                                 int biggest=0;
464                                 for(int i=0; i<lst.length;i++)
465                                 {
466                                         if( scores[i] > biggest )
467                                         {
468                                                 biggest=scores[i];
469                                                 top=i;
470                                         }
471                                 }
472                                 
473                                 if(biggest!=0)
474                                 {
475                                         lstAccounts.setSelection(top);
476                                 }
477                         }
478                 });
479                 
480                 log("Welcome!\nConnect your Final Key and enter password.\nThen press connect.\nPress the button when it blinks.\n----------\n");
481
482
483                 shell.addShellListener( new ShellListener() {
484                         
485                         public void shellIconified(ShellEvent e) {
486
487                         }
488
489                         public void shellDeiconified(ShellEvent e) {
490                                 // TODO Auto-generated method stub
491                                 
492                         }
493                         
494                         public void shellDeactivated(ShellEvent e) {
495                                 // TODO Auto-generated method stub
496                                 
497                         }
498                         
499                         public void shellClosed(ShellEvent e) {
500                                 shutDownApp();
501                                 
502                         }
503                         
504                         public void shellActivated(ShellEvent e) {
505                                 // TODO Auto-generated method stub
506                                 
507                         }
508                 } );
509                 
510
511
512         }
513
514
515
516         @Override
517         public PopupMenu getPopup() {
518                 return this.popup;
519         }
520
521         @Override
522         public void serialEvent(SerialState state) {
523                 switch(state)
524                 {
525                 case Connected:
526                         shell.setText("Final Key (Connected)");
527                         btnConnect.setText("Disconnect");
528                         btnConnect.setVisible(true);
529                         //Should we hide?
530                         if( prefs.getBoolean(PREF_AUTOHIDE, false) == true)
531                         {
532                                 hideToTray();
533                         }
534                         log("* Connected *");
535                         break;
536                 case Connecting:
537                         shell.setText("Final Key (Connecting...)");
538                         txtPsw.setVisible(false);
539                         txtDev.setVisible(false);
540                         btnConnect.setVisible(false);
541                         lblPort.setVisible(false);
542                         lblPassword.setVisible(false);
543                         chkAutoHide.setVisible(false);
544                         break;
545                 case Disconnected:
546                         fkSerial=null;
547                         shell.setText("Final Key (Not connected)");
548                         txtPsw.setVisible(true);
549                         txtDev.setVisible(true);
550                         btnConnect.setText("Connect");
551                         btnConnect.setVisible(true);
552                         lblPort.setVisible(true);
553                         lblPassword.setVisible(true);
554                         chkAutoHide.setVisible(true);
555                         clearSystray();
556                         if(lastState != state)
557                         {
558                                 log("* Disconnected *");
559                         }
560                         break;
561                 default:
562                         break;
563                 }
564                 lastState=state;
565                 cmpConnect.layout();
566         }
567 }