Added restore functionality to GUI.
[FinalKeyGui.git] / src / fkgui / Backup.java
1 package fkgui;
2
3 import java.io.File;
4 import java.io.FileOutputStream;
5 import org.eclipse.swt.widgets.Dialog;
6 import org.eclipse.swt.widgets.Display;
7 import org.eclipse.swt.widgets.Event;
8 import org.eclipse.swt.widgets.FileDialog;
9 import org.eclipse.swt.widgets.Listener;
10 import org.eclipse.swt.widgets.MessageBox;
11 import org.eclipse.swt.widgets.Shell;
12 import org.eclipse.swt.widgets.Composite;
13 import org.eclipse.swt.SWT;
14 import org.eclipse.swt.events.SelectionAdapter;
15 import org.eclipse.swt.events.SelectionEvent;
16 import org.eclipse.swt.layout.FormLayout;
17 import org.eclipse.swt.layout.FormData;
18 import org.eclipse.swt.layout.FormAttachment;
19 import org.eclipse.swt.widgets.Label;
20 import org.eclipse.swt.widgets.Button;
21
22 import org.eclipse.wb.swt.SWTResourceManager;
23 import org.eclipse.swt.widgets.Text;
24 import org.eclipse.swt.widgets.ProgressBar;
25
26 public class Backup extends Dialog implements FkActionEventListener {
27
28         protected Object result;
29         protected Shell shell;
30
31         /**
32          * Create the dialog.
33          * @param parent
34          * @param style
35          */
36         public Backup(Shell parent, int style) {
37                 super(parent, style);
38         }
39
40         /**
41          * Open the dialog.
42          * @return the result
43          */
44         private boolean restoreBackup;
45         private File backupFile;
46         private Backup mySelf; 
47         private Composite cmpBackupFileSelect;
48         private Composite cmpWaiting;
49         private Composite cmpStatus;
50         Animation animation;
51         Label lblFileName;
52         Button btnBackup;
53         Label lblMsg;
54         private Text txtFileName;
55         private Button btnBrowse;
56         private String fileName;
57         private Label lblStatusVerified;
58         private Button btnStatusOk;
59         private ProgressBar progressBar=null;
60
61
62         public Object open(boolean _restoreBackup) {
63                 restoreBackup=_restoreBackup;
64                 createContents();
65                 shell.open();
66                 shell.layout();
67                 mySelf = this;
68
69                 if( _restoreBackup )
70                 {
71                         setText("FinalKey - Restore");
72                 } else {
73                         setText("FinalKey - Backup");
74                 }
75
76                 Display display = getParent().getDisplay();
77                 while (!shell.isDisposed()) {
78                         if (!display.readAndDispatch()) {
79                                 display.sleep();
80                         }
81                 }
82                 return result;
83         }
84
85         /**
86          * Create contents of the dialog.
87          */
88         private void createContents() {
89                 shell = new Shell(getParent(), SWT.DIALOG_TRIM);
90                 shell.setSize(512, 302);
91                 shell.setText(getText());
92                 shell.setLayout(new FormLayout());
93                 
94                 //createStatusView("test");
95                 //createWaitingScreen("Press the button now to take a backup of your FinalKey.");
96                 //createBackupFileSelection();
97
98                 createBackupFileSelection();
99                 
100         }
101
102         private void createWaitingScreen(String msg) {
103                 
104                 cmpWaiting = new Composite(shell, SWT.NONE);
105                 FormData fd_cmpWaiting = new FormData();
106                 fd_cmpWaiting.top = new FormAttachment(0);
107                 fd_cmpWaiting.left = new FormAttachment(0);
108                 fd_cmpWaiting.bottom = new FormAttachment(0, 277);
109                 fd_cmpWaiting.right = new FormAttachment(0, 510);
110                 cmpWaiting.setLayoutData(fd_cmpWaiting);
111                 
112                 Label lblMsg = new Label(cmpWaiting, SWT.NONE);
113                 lblMsg.setBounds(48, 10, 393, 43);
114                 
115                 lblMsg.setText(msg);
116                 
117                 animation = new Animation(cmpWaiting, SWT.NONE, 4);
118                 animation.setBounds(10, 10, 32, 32);
119
120                 animation.setVisible(true);
121                 animation.setPlaying(true);
122                 
123         }
124
125         private void createBackupFileSelection() {
126                 cmpBackupFileSelect = new Composite(shell, SWT.NONE);
127                 cmpBackupFileSelect.setLayout(new FormLayout());
128                 FormData fd_cmpBackupFileSelect = new FormData();
129                 fd_cmpBackupFileSelect.bottom = new FormAttachment(0, 277);
130                 fd_cmpBackupFileSelect.right = new FormAttachment(0, 510);
131                 fd_cmpBackupFileSelect.top = new FormAttachment(0);
132                 fd_cmpBackupFileSelect.left = new FormAttachment(0);
133                 cmpBackupFileSelect.setLayoutData(fd_cmpBackupFileSelect);
134
135                 lblMsg = new Label(cmpBackupFileSelect, SWT.NONE);
136                 FormData fd_lblNewLabel = new FormData();
137                 fd_lblNewLabel.right = new FormAttachment(100, -91);
138                 fd_lblNewLabel.left = new FormAttachment(0, 10);
139                 lblMsg.setLayoutData(fd_lblNewLabel);
140
141                 if(!restoreBackup)
142                 {
143                         lblMsg.setText("About backup:\nIt is a good idea to backup your FinalKey so you don't\nlose all your logins if you lose your FinalKey or it breaks.\n\nSecurity:\nThe FinalKey backup files are encrypted, but you should\nnever keep them on your computer or in a place where\nsomeone else may steal them. Keep your backup on\nan offline storage medium in a safe place.\n");
144                 } else {
145                         lblMsg.setText("Important! Read  first!\nThis will overwrite all data on your FinalKey with the data\nfrom the backup-file you select!\n\nThe password needed to unlock your FinalKey will be\nthe password that was used at the time that the backup\nwas made. If you do not know the password of the\nbackup file, your FinalKey is useless.\n");
146                 }
147
148                 btnBackup = new Button(cmpBackupFileSelect, SWT.NONE);
149                 if(!restoreBackup)
150                 {
151                         btnBackup.setText("Backup");
152                         btnBackup.setImage(SWTResourceManager.getImage(Backup.class, "/fkgui/gfx/backup.png"));
153                 } else {
154                         btnBackup.setText("Restore");
155                         btnBackup.setImage(SWTResourceManager.getImage(Backup.class, "/fkgui/gfx/restore.png"));
156                 }
157                 FormData fd_btnBackup = new FormData();
158                 fd_btnBackup.bottom = new FormAttachment(100, -10);
159                 fd_btnBackup.right = new FormAttachment(100, -10);
160                 fd_btnBackup.top = new FormAttachment(0, 234);
161                 btnBackup.setLayoutData(fd_btnBackup);
162                 btnBackup.setEnabled(false);
163
164
165                 if(!restoreBackup)
166                 {
167                         btnBackup.addSelectionListener( new SelectionAdapter() {
168                                 public void widgetSelected(SelectionEvent e) {
169
170                                         fileName=txtFileName.getText();
171
172                                         try {
173
174                                                 backupFile = new File(fileName);
175
176                                                 if(backupFile.createNewFile())
177                                                 {
178                                                         MessageBox m = new MessageBox(shell, SWT.ICON_INFORMATION);
179                                                         m.setText("Ready to backup");
180                                                         m.setMessage("When you press OK, The FinalKey will start blinking, you then have 5 seconds to press the button to allow backup.");
181                                                         shell.setEnabled(false);
182                                                         m.open();
183                                                         FkManager.getInstance().backup(backupFile, mySelf);
184                                                         shell.setEnabled(true);
185
186                                                 } else {
187                                                         MessageBox m = new MessageBox(shell, SWT.ICON_ERROR);
188                                                         m.setText("File exists");
189                                                         m.setMessage("Will not overwrite an existing file.\nChose a new name or delete the existing file.");
190                                                         shell.setEnabled(false);
191                                                         m.open();
192                                                         shell.setEnabled(true);
193                                                 }
194
195                                         } catch(Exception ex)
196                                         {
197                                                 fileName="";
198                                                 txtFileName.setText("");
199                                                 btnBackup.setEnabled(false);
200                                                 MessageBox m = new MessageBox(shell, SWT.ICON_ERROR);
201                                                 m.setText("Could not create file.");
202                                                 m.setMessage("The file could not be created: "+ex.getLocalizedMessage() );
203                                                 shell.setEnabled(false);
204                                                 m.open();
205                                                 shell.setEnabled(true);
206                                         }
207
208                                 }
209
210                         });
211                 } else {
212                         btnBackup.addSelectionListener( new SelectionAdapter() {
213                                 public void widgetSelected(SelectionEvent e) {
214
215                                         fileName=txtFileName.getText();
216
217
218                                         try {
219
220                                                 backupFile = new File(fileName);
221
222                                                 if( backupFile.canRead() )
223                                                 {
224                                                         MessageBox m = new MessageBox(shell, SWT.ICON_WARNING | SWT.YES | SWT.NO);
225                                                         m.setText("Ready to Restore");
226                                                         m.setMessage("Press yes to restore the backup onto the Finalkey. You will have 5 seconds to press the button on your FinalKey to allow restore.\nIf you do not want to overwrite your FinalKey, press No to abort.");
227                                                         shell.setEnabled(false);
228                                                         if( m.open() == SWT.YES )
229                                                         {
230                                                                 FkManager.getInstance().restore(backupFile, mySelf);
231                                                         } else {
232                                                                 m = new MessageBox(shell, SWT.ICON_INFORMATION);
233                                                                 m.setText("Aborted");
234                                                                 m.setMessage("Restore was aborted.");
235                                                                 m.open();
236                                                                 shell.close();
237                                                         }
238
239                                                 } else {
240                                                         MessageBox m = new MessageBox(shell, SWT.ICON_ERROR);
241                                                         m.setText("File exists");
242                                                         m.setMessage("Will not overwrite an existing file.\nChose a new name or delete the existing file.");
243                                                         shell.setEnabled(false);
244                                                         m.open();
245                                                         shell.setEnabled(true);
246                                                 }
247
248                                         } catch(Exception ex)
249                                         {
250                                                 fileName="";
251                                                 txtFileName.setText("");
252                                                 btnBackup.setEnabled(false);
253                                                 MessageBox m = new MessageBox(shell, SWT.ICON_ERROR);
254                                                 m.setText("Could not create file.");
255                                                 m.setMessage("The file could not be created: "+ex.getLocalizedMessage() );
256                                                 shell.setEnabled(false);
257                                                 m.open();
258                                                 shell.setEnabled(true);
259                                         }
260
261                                 }
262
263                         });
264
265                 } //Restore
266                 fd_btnBackup.left = new FormAttachment(0, 371);
267
268                 Label lblThisSavesThe = new Label(cmpBackupFileSelect, SWT.NONE);
269                 fd_lblNewLabel.top = new FormAttachment(lblThisSavesThe, 18);
270                 lblThisSavesThe.setFont(SWTResourceManager.getFont("Sans", 10, SWT.BOLD));
271                 FormData fd_lblThisSavesThe = new FormData();
272                 fd_lblThisSavesThe.top = new FormAttachment(0, 10);
273                 fd_lblThisSavesThe.left = new FormAttachment(lblMsg, 0, SWT.LEFT);
274                 fd_lblThisSavesThe.bottom = new FormAttachment(100, -245);
275                 fd_lblThisSavesThe.right = new FormAttachment(100, -68);
276                 lblThisSavesThe.setLayoutData(fd_lblThisSavesThe);
277
278                 if(!restoreBackup)
279                 {
280                         lblThisSavesThe.setText("Save the contents of FinalKey to a file");
281                 } else {
282                         lblThisSavesThe.setText("Restore the contents of a file onto FinalKey");
283                 }
284
285                 lblFileName = new Label(cmpBackupFileSelect, SWT.NONE);
286                 fd_lblNewLabel.bottom = new FormAttachment(100, -81);
287                 lblFileName.setAlignment(SWT.RIGHT);
288                 lblFileName.setText("File:");
289                 FormData fd_lblFileName = new FormData();
290                 fd_lblFileName.top = new FormAttachment(lblMsg, 49);
291                 fd_lblFileName.bottom = new FormAttachment(100, -10);
292                 fd_lblFileName.left = new FormAttachment(0, 10);
293                 lblFileName.setLayoutData(fd_lblFileName);
294
295                 txtFileName = new Text(cmpBackupFileSelect, SWT.BORDER);
296                 fd_lblFileName.right = new FormAttachment(100, -463);
297                 FormData fd_txtFileName = new FormData();
298                 fd_txtFileName.top = new FormAttachment(lblMsg, 49);
299                 fd_txtFileName.bottom = new FormAttachment(100, -10);
300                 fd_txtFileName.left = new FormAttachment(lblFileName, 6);
301                 txtFileName.setLayoutData(fd_txtFileName);
302                 txtFileName.addListener(SWT.CHANGED, new Listener() {
303
304                         @Override
305                         public void handleEvent(Event arg0) {
306                                 if( txtFileName.getText().length() > 0 )
307                                 {
308                                         btnBackup.setEnabled(true);
309                                 } else {
310                                         btnBackup.setEnabled(false);
311                                 }
312                         }
313                 });
314
315                 btnBrowse = new Button(cmpBackupFileSelect, SWT.NONE);
316                 fd_txtFileName.right = new FormAttachment(btnBrowse, -6);
317                 FormData fd_btnBrowse = new FormData();
318                 fd_btnBrowse.top = new FormAttachment(lblMsg, 49);
319                 fd_btnBrowse.bottom = new FormAttachment(btnBackup, 0, SWT.BOTTOM);
320                 fd_btnBrowse.right = new FormAttachment(btnBackup, -6);
321                 btnBrowse.setLayoutData(fd_btnBrowse);
322                 btnBrowse.setText("...");
323                 btnBrowse.addSelectionListener( new SelectionAdapter() {
324                         public void widgetSelected(SelectionEvent e) {
325                                 FileDialog fd = new FileDialog(shell, SWT.SAVE );
326                                 String[] ext = { "*.fkb", "*.*"  };
327                                 String[] extN = { "FinalKey Backup Files", "All Files"};
328
329                                 //Try to start the selection dialog in the existing information, if it is correct and exist
330                                 fileName = txtFileName.getText();
331                                 if( fileName.length() != 0 )
332                                 {
333                                         File testFile = new File(fileName);
334                                         String dir = testFile.getParent();
335                                         if( dir != null )
336                                         {
337                                                 fd.setFilterPath(dir);
338
339                                                 if( (!restoreBackup && !testFile.isFile()) || (restoreBackup && testFile.isFile()) )
340                                                 {
341                                                         fd.setFileName(testFile.getName());
342                                                 }
343                                         }
344                                 }
345
346                                 if(restoreBackup)
347                                 {
348                                         fd.setFileName("");
349                                 }
350
351                                 fd.setFilterExtensions( ext );
352                                 fd.setFilterNames(extN);
353
354                                 fileName = fd.open();
355
356                                 if( fileName != null )
357                                 {
358
359                                         System.out.println("FileName: " + fileName);
360                                         txtFileName.setText(fileName);
361                                         btnBackup.setEnabled(true);
362                                 }
363                         }
364                 });
365
366         }
367
368         @Override
369         public void fkActionEvent(FkActionEvent event) {
370                 MessageBox m;
371                 System.out.println(event);
372
373                 //Handle errors differently when we are taking bacup
374                 if( !restoreBackup )
375                 {
376                         switch( event.type )
377                         {
378                         case ACTION_ABORTED:
379                                 backupFile.delete();
380                                 m = new MessageBox(shell, SWT.ICON_WARNING| SWT.YES| SWT.NO);
381                                 m.setText("Backup failed");
382                                 m.setMessage("You did not press the button within 5 seconds, or you held down the button to abort the backup. Try again ?");
383
384                                 if( m.open() == SWT.YES )
385                                 {
386                                         cmpWaiting.dispose();
387                                         createBackupFileSelection();
388                                         shell.layout();
389                                 } else {
390                                         shell.close();
391                                 }
392                                 break;
393                         case ACTION_ERROR:
394                                 lblStatusVerified.setText("Valid: No - Validation failed.");
395
396                                 m = new MessageBox(shell, SWT.ICON_ERROR| SWT.YES| SWT.NO);
397                                 m.setText("Checksum Error");
398                                 m.setMessage("There were one or more errors when verifying the backup data, this may indicate a bad connection or a hardware-malfunction on the FinalKey.\nThe Backup File can NOT be restored onto the FinalKey, but it may be manually repaired by someone with a hex-editor and too much free-time. Do you want to delete the corrupted file ?");
399                                 if( m.open() == SWT.YES )
400                                 {
401                                         backupFile.delete();
402                                 } else {
403                                         backupFile.renameTo( new File(fileName+"-failed"));
404                                         File crashLog = new File(fileName+"-errorlog.txt");
405                                         FileOutputStream fout;
406                                         try {
407                                                 fout = new FileOutputStream( crashLog );
408                                                 fout.write( event.data.getBytes() );
409                                                 fout.close();
410                                         } catch (Exception e) {
411                                                 e.printStackTrace();
412                                         }
413
414                                 }
415                                 shell.close();
416
417                                 break;
418                         case ACTION_OKAY:
419                                 lblStatusVerified.setText("Valid: Yes");
420                                 progressBar.setSelection(66000);
421                                 m=new MessageBox(shell, SWT.ICON_INFORMATION);
422                                 m.setText("Backup successful");
423                                 m.setMessage("Backup was verified and saved.");
424                                 m.open();
425                                 shell.close();
426                                 break;
427                         case ACTION_WAITING:
428                                 cmpBackupFileSelect.dispose();
429                                 createWaitingScreen("Press the FinalKey button to allow backup.\nPress and hold, or wait, to abort.");
430                                 shell.layout();
431                                 break;
432                         case ACTION_WORKING:
433                                 cmpWaiting.dispose();
434                                 createStatusView("Backing up...");
435                                 shell.layout();
436                                 shell.setEnabled(false);
437                                 break;
438                         case PROGRESS_UPDATE:
439                                 if(progressBar!= null )
440                                 {
441                                         progressBar.setSelection( Integer.parseInt( event.data ) );
442                                 }
443                                 break;
444                         case UNEXPECTED_ACTION_RESULT_ERROR:
445                                 break;
446                         default:
447                                 break;
448                         
449                         }
450                 } else {
451                         boolean disconnect=false;
452                         switch(event.type)
453                         {
454                         case ACTION_ABORTED:
455                                 m = new MessageBox(shell, SWT.ICON_ERROR);
456                                 m.setText("Restore aborted");
457                                 m.setMessage("You did not press the button within 5 second, restore aborted.");
458                                 m.open();
459                                 shell.close();
460                                 break;
461                         case ACTION_ERROR:
462                                 disconnect=true;
463                                 m = new MessageBox(shell, SWT.ICON_ERROR);
464                                 m.setText("Restore Error");
465                                 m.setMessage("Something went wrong, the backup was not fully restored, error: "+event.data);
466                                 m.open();
467                                 break;
468                         case ACTION_OKAY:
469                                 lblStatusVerified.setText("Restore complete.");
470                                 lblStatusVerified.setVisible(true);
471                                 m = new MessageBox(shell, SWT.ICON_INFORMATION);
472                                 m.setText("Restore success");
473                                 m.setMessage("The backup has been restored to your FinalKey.\nPress the FinalKey button now, so the blinking stops.");
474                                 FkManager.getInstance().disconnect();
475                                 m.open();
476                                 shell.close();
477                                 break;
478                         case ACTION_WAITING:
479                                 shell.setEnabled(false);
480                                 cmpBackupFileSelect.dispose();
481                                 createWaitingScreen("Press the FinalKey button to allo restore.\nPress and hold, or wait, to abort.");
482                                 shell.layout();
483                                 break;
484                         case ACTION_WORKING:
485                                 cmpWaiting.dispose();
486                                 createStatusView("Writing data to FinalKey...");
487                                 lblStatusVerified.setVisible(false);
488                                 shell.layout();
489                                 break;
490                         case FILE_ERROR:
491                                 m = new MessageBox(shell, SWT.ICON_ERROR);
492                                 m.setText("Restore Aborted");
493                                 m.setMessage("There was a problem with the backup file: "+event.data);
494                                 m.open();
495                                 shell.setEnabled(true);
496                                 break;
497                         case PROGRESS_UPDATE:
498                                 progressBar.setSelection(Integer.parseInt(event.data));
499                                 break;
500                         default:
501                                 break;
502
503                         }
504
505                         if(event.type == FkActionEventType.STATE_ERROR )
506                         {
507                                 m = new MessageBox(shell, SWT.ICON_ERROR);
508                                 m.setText("State error");
509                                 m.setMessage("The FinalKey was in an unexpected state, operation failed.");
510                                 m.open();
511                                 disconnect=true;
512                         }
513
514                         if(disconnect)
515                         {
516                                 FkManager.getInstance().disconnect();
517                                 shell.close();
518                         }
519
520                 }
521
522         }
523
524         private void createStatusView(String msg) {
525                 cmpStatus = new Composite(shell, SWT.NONE);
526                 cmpStatus.setLayout(new FormLayout());
527                 FormData fd_cmpStatus = new FormData();
528                 fd_cmpStatus.bottom = new FormAttachment(0, 277);
529                 fd_cmpStatus.right = new FormAttachment(0, 510);
530                 fd_cmpStatus.top = new FormAttachment(0);
531                 fd_cmpStatus.left = new FormAttachment(0);
532                 cmpStatus.setLayoutData(fd_cmpStatus);
533
534                 Label lblStatusMsg = new Label(cmpStatus, SWT.NONE);
535                 FormData fd_lblStatusMsg = new FormData();
536                 fd_lblStatusMsg.right = new FormAttachment(0, 500);
537                 fd_lblStatusMsg.top = new FormAttachment(0, 10);
538                 fd_lblStatusMsg.left = new FormAttachment(0, 10);
539                 lblStatusMsg.setLayoutData(fd_lblStatusMsg);
540                 lblStatusMsg.setText(msg);
541
542                 progressBar = new ProgressBar(cmpStatus, SWT.NONE);
543                 progressBar.setToolTipText("Progress");
544                 progressBar.setMaximum(66000);
545                 FormData fd_progressBar = new FormData();
546                 fd_progressBar.right = new FormAttachment(lblStatusMsg, 0, SWT.RIGHT);
547                 fd_progressBar.top = new FormAttachment(lblStatusMsg, 6);
548                 fd_progressBar.left = new FormAttachment(0, 10);
549                 progressBar.setLayoutData(fd_progressBar);
550
551                 lblStatusVerified = new Label(cmpStatus, SWT.NONE);
552                 FormData fd_lblStatusVerified = new FormData();
553                 fd_lblStatusVerified.right = new FormAttachment(lblStatusMsg, 0, SWT.RIGHT);
554                 fd_lblStatusVerified.top = new FormAttachment(progressBar, 6);
555                 fd_lblStatusVerified.left = new FormAttachment(lblStatusMsg, 0, SWT.LEFT);
556                 lblStatusVerified.setLayoutData(fd_lblStatusVerified);
557                 lblStatusVerified.setText("Valid: Not verified yet");
558
559                 btnStatusOk = new Button(cmpStatus, SWT.NONE);
560                 fd_lblStatusVerified.bottom = new FormAttachment(btnStatusOk, -6);
561                 FormData fd_btnStatusOk = new FormData();
562                 fd_btnStatusOk.bottom = new FormAttachment(100, -10);
563                 fd_btnStatusOk.right = new FormAttachment(100, -10);
564                 btnStatusOk.setLayoutData(fd_btnStatusOk);
565                 btnStatusOk.setText("OK");
566                 btnStatusOk.setVisible(false);
567
568         }
569 }