Source code: com/tanksoftware/juk/Copernicus.java
1 /*
2 * Copernicus
3 * Copyright (C) 2002-2003 William Denniss
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program i"s distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License
16 * along with this program in the "COPYING.txt" file; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
18 * MA 02111-1307 USA or visit http://www.gnu.org/
19 */
20
21 package com.tanksoftware.juk;
22
23 import java.awt.*;
24 import java.awt.event.*;
25 import javax.swing.*;
26 import javax.swing.event.*;
27 import java.io.*;
28 import java.util.List;
29 import java.util.HashMap;
30 import java.util.ArrayList;
31 import java.util.LinkedList;
32
33 import com.tanksoftware.util.*;
34
35 import net.jtank.layout.*;
36 import net.jtank.io.Ini;
37 import net.jtank.io.IniSection;
38 import net.jtank.io.SunFileFilter;
39 import net.jtank.io.FileUtil;
40 import net.jtank.io.WXML;
41 import net.jtank.io.WXMLSection;
42 import net.jtank.protocol.OneTimeNOCList;
43 import net.jtank.protocol.MultiLingual;
44 import net.jtank.util.UIUtil;
45 import net.jtank.util.BrowserLauncher;
46
47
48
49 /**
50 * The main classes for the running of the application Copernicus.
51 *
52 * <p>Title: Copernicus</p>
53 * <p>Description: Internet Password and Username tracking software</p>
54 * <p>Copyright: Copyright (c) 2002 William Denniss</p>
55 * <p>Company: Tank Software</p>
56 * @author William Denniss
57 * @version 1.4.0
58 */
59
60 public class Copernicus extends JFrame {
61
62 public static final String PROGRAM_NAME = "Copernicus";
63 public static final String VERSION_NUMBER = "1.4.0";
64 public static final String DATE_CREATED = "05 April 2002";
65 public static final String DATE_UPDATED = "17 August 2002";
66 public static final String AUTHOR = "William Denniss";
67
68 private static WillTank willTankPanel = new WillTank(PROGRAM_NAME, VERSION_NUMBER, DATE_UPDATED);
69 private static final String INI_FILE_NAME = "copernicus.ini";
70 private static final String pname = "copernicus";
71 private static final String defaultLAF = "com.incors.plaf.kunststoff.KunststoffLookAndFeel";
72
73
74 private SunFileFilter wxmlFilter;
75
76 private String lastLoadedFile = "";
77
78 private int menulimit = 20;
79
80
81 // Stores a list of all components which are set to disabled when nobody is logged in.
82 private java.util.List componentEnableList = new LinkedList ();
83
84
85 private JMenu menuUsers;
86 private JMenu menuSites = new JMenu();
87 private XYLayout xYLayout1 = new XYLayout();
88
89 private JMenu menuLanguages;
90
91
92 private String baseDirectory = "";
93 private List users = new ArrayList();
94 private HashMap users_name = new HashMap();
95 private HashMap users_filename = new HashMap();
96 private Ini mainIni;
97
98 private WXML currentUser;
99 private WXMLSection currentSite;
100 private WXMLSection currentLogin;
101
102 private String currentUserFileName;
103 private int lastUser = 0;
104
105 private WXMLSection [] currentSortedSites;
106
107
108
109
110 private JTextField siteNameText = new JTextField();
111 private JButton lookup = new JButton();
112 private JTextField loginNameText = new JTextField(11);
113 private JLabel loginLabel = new JLabel();
114 private JTextField usernameText = new JTextField(25);
115 private JLabel usernameLabel = new JLabel();
116 private JTextField passwordText = new JTextField(25);
117 private JLabel passwordLabel = new JLabel();
118 private JLabel commentLabel = new JLabel();
119 private JScrollPane commentTextScrollPane = new JScrollPane();
120 private JTextArea commentText = new JTextArea();
121 private JCheckBox useEncryption = new JCheckBox();
122 private JMenuItem menuCreateNewUser;
123 private JMenuItem menuLogout = new JMenuItem();
124
125 // The main GUI panel
126 private JSplitPane split;
127
128
129 private int searchNum = 0;
130 //private int searchNumLogin = 0;
131
132
133
134 private String currentUserFile = "";
135
136
137
138 //new
139 private JList siteList;
140 private JTextField filter;
141 private JButton nextAccountButton;
142
143 private JCheckBoxMenuItem mUseEncryption;
144
145
146 private JTextField username;
147 private JTextField password;
148 private JTextArea comment;
149
150 private WXMLSection [] logins;
151 private WXMLSection lastLogin;
152 private WXMLSection lastSite;
153
154 private JComboBox accList;
155
156 int selSite = -1;
157 int selLogin = 0;
158
159 private MultiLingual lingual = new MultiLingual("copernicus", "GBR", "data/langpack/");
160
161 // is true when the current user is a brand new user and needs special treatment
162 private boolean newuser = false;
163
164 // true if a save is needed
165 private boolean saveConfirm = false;
166
167 public Copernicus() {
168
169
170
171 /*
172 *
173 * Loads the INI file.
174 *
175 */
176
177 mainIni = new Ini (baseDirectory + Copernicus.INI_FILE_NAME);
178 try {
179 mainIni.readIni(new BufferedReader(new FileReader(mainIni.getName())));
180
181 } catch (IOException e) {
182 try {
183 mainIni.addSection(new IniSection("MAIN_SETTINGS"));
184 mainIni.writeIni(new BufferedWriter(new FileWriter(mainIni.getName())));
185 } catch (IOException e2) {
186 }
187 }
188
189 JPopupMenu mSitePopup;
190 JPopupMenu mAccountPopup;
191
192 String lookAndFeel = mainIni.getSectionAttributeStr("MAIN_SETTINGS", "lookandfeel", "default");
193 UIUtil.setDefaultLAF(defaultLAF);
194 System.out.print(UIUtil.changeLookAndFeel(lookAndFeel));
195 mainIni.setSectionAttribute("MAIN_SETTINGS", "lookandfeel", lookAndFeel);
196
197
198 /*
199 *
200 * MENU
201 *
202 */
203 JMenuBar menu = new JMenuBar();
204 this.setJMenuBar(menu);
205 {
206 JMenu mOptions = new JMenu ("File");
207 menu.add(mOptions);
208 lingual.register(mOptions);
209 mOptions.setMnemonic(KeyEvent.VK_F);
210 {
211
212
213 menuUsers = new JMenu("Recent User");
214 lingual.register(menuUsers);
215 menuCreateNewUser = new JMenuItem("New");
216 lingual.register(menuCreateNewUser);
217 JMenuItem menuAddUserFile = new JMenuItem("Open");
218 lingual.register(menuAddUserFile);
219
220 JMenuItem menuItemSave = new JMenuItem ("Save");
221 lingual.register(menuItemSave);
222 componentEnableList.add(menuItemSave);
223 JMenuItem menuSaveAs = new JMenuItem("Save As");
224 lingual.register(menuSaveAs);
225 componentEnableList.add(menuSaveAs);
226 JMenuItem menuSaveAsCopy = new JMenuItem("Save As Copy");
227 lingual.register(menuSaveAsCopy);
228 componentEnableList.add(menuSaveAsCopy);
229
230 JMenuItem menuLogout = new JMenuItem("Close");
231 lingual.register(menuLogout);
232 componentEnableList.add(menuLogout);
233
234 JMenuItem mExit = new JMenuItem ("Exit");
235 lingual.register(mExit);
236
237
238 mOptions.add(menuUsers);
239 mOptions.add(menuCreateNewUser);
240 mOptions.add(menuAddUserFile);
241 mOptions.addSeparator();
242
243 mOptions.add(menuItemSave);
244 mOptions.add(menuSaveAs);
245 mOptions.add(menuSaveAsCopy);
246 mOptions.addSeparator();
247 mOptions.add(menuLogout);
248 mOptions.addSeparator();
249
250 mOptions.add(mExit);
251
252 menuUsers.setIcon(new ImageIcon ("data/images/blank.png"));
253 menuUsers.setMnemonic(KeyEvent.VK_R);
254
255 menuCreateNewUser.setMnemonic(KeyEvent.VK_N);
256 menuCreateNewUser.setIcon(new ImageIcon ("data/images/new.png"));
257 menuCreateNewUser.addActionListener(new java.awt.event.ActionListener() {
258 public void actionPerformed(ActionEvent e) {
259 newUser();
260 }
261 });
262
263 menuAddUserFile.setMnemonic(KeyEvent.VK_O);
264 menuAddUserFile.setIcon(new ImageIcon ("data/images/open.png"));
265 menuAddUserFile.addActionListener(new java.awt.event.ActionListener() {
266 public void actionPerformed(ActionEvent e) {
267 addUserFile();
268 }
269 });
270
271 menuItemSave.setIcon(new ImageIcon ("data/images/save.png"));
272 menuItemSave.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_S, ActionEvent.CTRL_MASK));
273 menuItemSave.setMnemonic(KeyEvent.VK_S);
274 menuItemSave.addActionListener(new java.awt.event.ActionListener() {
275 public void actionPerformed(ActionEvent e) {
276 save_actionPerformed(e);
277 }
278 });
279
280 menuSaveAs.setMnemonic(KeyEvent.VK_A);
281 menuSaveAs.setIcon(new ImageIcon ("data/images/blank.png"));
282 menuSaveAs.addActionListener(new java.awt.event.ActionListener() {
283 public void actionPerformed(ActionEvent e) {
284 saveUserFileAs_actionPerformed(e, false);
285 }
286 });
287
288 menuSaveAsCopy.setMnemonic(KeyEvent.VK_P);
289 menuSaveAsCopy.setIcon(new ImageIcon ("data/images/blank.png"));
290 menuSaveAsCopy.addActionListener(new java.awt.event.ActionListener() {
291 public void actionPerformed(ActionEvent e) {
292 saveUserFileAs_actionPerformed(e, true);
293 }
294 });
295
296 menuLogout.setMnemonic(KeyEvent.VK_C);
297 menuLogout.setIcon(new ImageIcon ("data/images/blank.png"));
298 menuLogout.addActionListener(new java.awt.event.ActionListener() {
299 public void actionPerformed(ActionEvent e) {
300 logout();
301 }
302 });
303
304 mExit.setIcon(new ImageIcon ("data/images/blank.png"));
305 mExit.setMnemonic(KeyEvent.VK_X);
306 mExit.addActionListener(new java.awt.event.ActionListener() {
307 public void actionPerformed(ActionEvent e) {
308 exitCopernicus();
309 }
310 });
311
312 }
313
314 JMenu mEdit = new JMenu ("Edit");
315 mEdit.setMnemonic(KeyEvent.VK_E);
316 menu.add(mEdit);
317 lingual.register(mEdit);
318 {
319
320 /*
321 * The Current User Menu
322 *
323 */
324 JMenu mUser = new JMenu ("User");
325 lingual.register(mUser);
326 componentEnableList.add(mUser);
327 mUser.setMnemonic(KeyEvent.VK_U);
328 //mUser.setIcon(new ImageIcon ("data/images/blank.png"));
329 {
330 // Construct and register
331 JMenuItem menuChangeName = new JMenuItem("Change Display Name");
332 lingual.register(menuChangeName);
333 mUseEncryption = new JCheckBoxMenuItem("Use Encryption");
334 lingual.register(mUseEncryption);
335 JMenuItem menuSetAsDefault = new JMenuItem("Set as default");
336 lingual.register(menuSetAsDefault);
337 JMenuItem menuDeleteCurrentUser = new JMenuItem("Delete");
338 lingual.register(menuDeleteCurrentUser);
339
340 // Build List
341 mUser.add(menuChangeName);
342 mUser.add(menuSetAsDefault);
343 mUser.add(mUseEncryption);
344 mUser.addSeparator();
345 mUser.add(menuDeleteCurrentUser);
346
347 // Listeners
348 //menuChangeName.setIcon(new ImageIcon ("data/images/blank.png"));
349 menuChangeName.setMnemonic(KeyEvent.VK_N);
350 menuChangeName.addActionListener(new java.awt.event.ActionListener() {
351 public void actionPerformed(ActionEvent e) {
352 editUsername_actionPerformed(null);
353 }
354 });
355
356 //menuSetAsDefault.setIcon(new ImageIcon ("data/images/blank.png"));
357 menuSetAsDefault.setMnemonic(KeyEvent.VK_D);
358 menuSetAsDefault.addActionListener(new java.awt.event.ActionListener() {
359 public void actionPerformed(ActionEvent e) {
360 setCurrentAsDefault();
361 }
362 });
363
364 //menuDeleteCurrentUser.setIcon(new ImageIcon ("data/images/blank.png"));
365 menuDeleteCurrentUser.setMnemonic(KeyEvent.VK_L);
366 menuDeleteCurrentUser.addActionListener(new java.awt.event.ActionListener() {
367 public void actionPerformed(ActionEvent e) {
368 deleteCurrentUser();
369 }
370 });
371
372 //useEncryption.setIcon(new ImageIcon ("data/images/blank.png"));
373 useEncryption.setMnemonic(KeyEvent.VK_C);
374 useEncryption.addActionListener(new java.awt.event.ActionListener() {
375 public void actionPerformed(ActionEvent e) {
376 useEncryption_actionPerformed(e);
377 }
378 });
379
380
381 }
382
383 /*
384 * Current Site Menu
385 *
386 */
387 JMenu mSite = new JMenu ("Site");
388 lingual.register(mSite);
389 componentEnableList.add(mSite);
390 mSitePopup = mSite.getPopupMenu();
391 mSite.setMnemonic(KeyEvent.VK_S);
392 //mSite.setIcon(new ImageIcon ("data/images/blank.png"));
393 {
394
395 JMenuItem mSAdd = new JMenuItem("Create New Site");
396 lingual.register(mSAdd);
397 JMenuItem mSRename = new JMenuItem("Rename");
398 lingual.register(mSRename);
399 JMenuItem mSDelete = new JMenuItem("Delete");
400 lingual.register(mSDelete);
401
402 mSite.add(mSAdd);
403 mSite.add(mSRename);
404 mSite.add(mSDelete);
405
406 mSAdd.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, ActionEvent.CTRL_MASK));
407 mSAdd.setMnemonic(KeyEvent.VK_N);
408 //mSAdd.setIcon(new ImageIcon ("data/images/blank.png"));
409 mSAdd.addActionListener(new java.awt.event.ActionListener() {
410 public void actionPerformed(ActionEvent e) {
411 System.out.println("HI!");
412 addNewSite();
413 }
414 });
415 mSRename.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F2, 0));
416 mSRename.setMnemonic(KeyEvent.VK_R);
417 //mSRename.setIcon(new ImageIcon ("data/images/blank.png"));
418 mSRename.addActionListener(new java.awt.event.ActionListener() {
419 public void actionPerformed(ActionEvent e) {
420 renameSite();
421 }
422 });
423
424 //mSDelete.setIcon(new ImageIcon ("data/images/blank.png"));
425 mSDelete.setMnemonic(KeyEvent.VK_D);
426 mSDelete.addActionListener(new java.awt.event.ActionListener() {
427 public void actionPerformed(ActionEvent e) {
428 deleteSite();
429 }
430 });
431
432 }
433
434 /*
435 * Current Account Menu
436 *
437 */
438 JMenu mAccount = new JMenu ("Login");;
439 lingual.register(mAccount);
440 componentEnableList.add(mAccount);
441 mAccount.setMnemonic(KeyEvent.VK_L);
442 //mAccount.setIcon(new ImageIcon ("data/images/blank.png"));
443 mAccountPopup = mAccount.getPopupMenu();
444 {
445 JMenuItem mAAdd = new JMenuItem("Enter New Account");;
446 lingual.register(mAAdd);
447 JMenuItem mARename = new JMenuItem("Rename");
448 lingual.register(mARename);
449 JMenuItem mADelete= new JMenuItem("Delete");
450 lingual.register(mADelete);
451
452 mAccount.add(mAAdd);
453 mAccount.add(mARename);
454 mAccount.add(mADelete);
455
456
457 mAAdd.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_L, ActionEvent.CTRL_MASK));
458 mAAdd.setMnemonic(KeyEvent.VK_N);
459 //mAAdd.setIcon(new ImageIcon ("data/images/blank.png"));
460 mAAdd.addActionListener(new java.awt.event.ActionListener() {
461 public void actionPerformed(ActionEvent e) {
462 addNewLogin();
463 }
464 });
465
466 mARename.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F3, 0));
467 mARename.setMnemonic(KeyEvent.VK_R);
468 //mARename.setIcon(new ImageIcon ("data/images/blank.png"));
469 mARename.addActionListener(new java.awt.event.ActionListener() {
470 public void actionPerformed(ActionEvent e) {
471 renameLogin();
472 }
473 });
474
475 //mADelete.setIcon(new ImageIcon ("data/images/blank.png"));
476 mADelete.setMnemonic(KeyEvent.VK_D);
477 mADelete.addActionListener(new java.awt.event.ActionListener() {
478 public void actionPerformed(ActionEvent e) {
479 deleteLogin();
480 }
481 });
482
483
484
485 }
486
487 mEdit.add(mUser);
488 mEdit.add(mSite);
489 mEdit.add(mAccount);
490
491
492 }
493
494
495
496
497 menu.add(Box.createHorizontalGlue());
498
499 /*
500 * Languages
501 */
502 menuLanguages = lingual.constructMenu();
503 menuLanguages.setMnemonic(KeyEvent.VK_L);
504 menu.add(menuLanguages);
505 {
506
507 if (menuLanguages != null) {
508 for (int i = 0; i < menuLanguages.getItemCount(); i++) {
509 JMenuItem item = menuLanguages.getItem(i);
510 item.addActionListener(new java.awt.event.ActionListener() {
511 public void actionPerformed(ActionEvent e) {
512 changeLanguage(((JMenuItem)e.getSource()).getText());
513 }
514 });
515
516 }
517 }
518 }
519
520 JMenu mHelp = new JMenu ("Help");
521 lingual.register(mHelp);
522 menu.add(mHelp);
523 mHelp.setMnemonic(KeyEvent.VK_H);
524 {
525 JMenuItem mHHelp = new JMenuItem("Help");
526 lingual.register(mHHelp);
527 JMenuItem mHAbout = new JMenuItem("About");
528 lingual.register(mHAbout);
529
530 mHelp.add(mHHelp);
531 mHelp.addSeparator();
532 mHelp.add(mHAbout);
533
534 mHHelp.setMnemonic(KeyEvent.VK_H);
535 mHHelp.addActionListener(new java.awt.event.ActionListener() {
536 public void actionPerformed(ActionEvent e) {
537 showHelpURL();
538 }
539 });
540
541 mHAbout.setMnemonic(KeyEvent.VK_A);
542 mHAbout.addActionListener(new java.awt.event.ActionListener() {
543 public void actionPerformed(ActionEvent e) {
544 willTankPanel.showDialog();
545 }
546 });
547 }
548 }
549
550
551
552 /*
553 *
554 * GUI
555 *
556 *
557 */
558 {
559 JPanel leftPanel = new JPanel();
560 {
561 // Filter Panel
562 JPanel filterPanel = new JPanel();
563 {
564 filterPanel.setLayout(new BorderLayout());
565 JLabel filterl = new JLabel ("Search:");
566 lingual.register(filterl);
567 filterPanel.add(filterl, BorderLayout.WEST);
568 filter = new JTextField (15);
569 filterPanel.add(filter, BorderLayout.CENTER);
570 }
571
572 // Site Listing
573 JScrollPane siteListScroller = new JScrollPane ();
574 {
575 siteList = new JList();
576 siteListScroller.getViewport().add(siteList);
577
578 MouseListener siteListener = new PopupListener (mSitePopup);
579 siteList.addMouseListener(siteListener);
580
581 siteList.addListSelectionListener(new ListSelectionListener () {
582 public void valueChanged(ListSelectionEvent e) {
583 if (e.getValueIsAdjusting())
584 return;
585
586 siteSelected();
587 }
588 });
589 }
590
591 // Button
592 JButton newSiteButton = new JButton("Create New Site");
593 lingual.register(newSiteButton);
594 newSiteButton.addActionListener(new java.awt.event.ActionListener() {
595 public void actionPerformed(ActionEvent e) {
596 addNewSite();
597 }
598 });
599
600 leftPanel.setLayout(new BorderLayout());
601 leftPanel.add(filterPanel, BorderLayout.NORTH);
602 leftPanel.add(siteListScroller, BorderLayout.CENTER);
603 leftPanel.add(newSiteButton, BorderLayout.SOUTH);
604 }
605
606
607 // Right Panel
608 JPanel rightPanel = new JPanel();
609 {
610
611 accList = new JComboBox();
612 MouseListener accountListener = new PopupListener (mAccountPopup);
613 accList.addMouseListener(accountListener);
614
615
616 nextAccountButton = new JButton(">");
617 nextAccountButton.addActionListener(new java.awt.event.ActionListener() {
618 public void actionPerformed(ActionEvent e) {
619 nextLogin();
620 }
621 });
622
623 accList.addItemListener(new ItemListener () {
624 public void itemStateChanged(ItemEvent e) {
625 loginSelected();
626 }
627
628 });
629
630
631 // Button
632 JPanel newAccountPanel = new JPanel();
633 JButton newAccountButton = new JButton("Enter New Account");
634 lingual.register(newAccountButton);
635 newAccountPanel.add(newAccountButton);
636
637 newAccountButton.addActionListener(new java.awt.event.ActionListener() {
638 public void actionPerformed(ActionEvent e) {
639 addNewLogin();
640 }
641 });
642
643 // Account Details
644
645 // Username
646 JLabel usernameLab = new JLabel(" Username: ");
647 lingual.register(usernameLab);
648 username = new JTextField();
649 JPanel usernamePane = new JPanel();
650
651 // Password
652 JLabel passwordLab = new JLabel(" Password: ");
653 lingual.register(passwordLab);
654 password = new JTextField();
655 JPanel passwordPane = new JPanel();
656
657 // Add Username and Password - and align
658 JPanel l = new JPanel ();
659 l.setLayout(new BorderLayout());
660 JPanel r = new JPanel ();
661 r.setLayout(new BorderLayout());
662 JPanel c = new JPanel ();
663 c.setLayout(new BorderLayout());
664 l.add(usernameLab, BorderLayout.NORTH);
665 l.add(passwordLab, BorderLayout.CENTER);
666 r.add(username, BorderLayout.NORTH);
667 r.add(password, BorderLayout.CENTER);
668 c.add(l, BorderLayout.WEST);
669 c.add(r, BorderLayout.CENTER);
670
671 // Comment
672 JLabel commentLab = new JLabel("Comment");
673 lingual.register(commentLab);
674 comment = new JTextArea ();
675 comment.setLineWrap(true);
676 comment.setWrapStyleWord(true);
677 JScrollPane commentPane = new JScrollPane ();
678 commentPane.getViewport().add(comment);
679
680
681
682 // Add Username, Password and Comment
683 JPanel upc2 = new JPanel ();
684 upc2.setLayout(new BorderLayout());
685 upc2.add(c, BorderLayout.NORTH);
686 upc2.add(commentPane, BorderLayout.CENTER);
687
688 upc2.addMouseListener(accountListener);
689
690
691 JPanel p2 = new JPanel();
692 p2.setLayout(new BorderLayout());
693 p2.add(nextAccountButton, BorderLayout.EAST);
694 p2.add(accList, BorderLayout.CENTER);
695
696
697
698 rightPanel.setLayout(new BorderLayout());
699 rightPanel.add(p2, BorderLayout.NORTH);
700 rightPanel.add(upc2, BorderLayout.CENTER);
701 rightPanel.add(newAccountButton, BorderLayout.SOUTH);
702
703 }
704
705
706
707 // Combindes both panels and adds to frame.
708 split = new JSplitPane (JSplitPane.HORIZONTAL_SPLIT, true, leftPanel, rightPanel);
709 this.getContentPane().add(split);
710 split.setDividerLocation(split.getMinimumDividerLocation());
711 }
712
713
714 setTitle("Copernicus");
715 this.pack();
716 setIconImage(new ImageIcon("data/Copernicus/copernicus.gif").getImage());
717
718
719 // Sets up the file filter
720 wxmlFilter = new SunFileFilter();
721 wxmlFilter.addExtension("wxml");
722 wxmlFilter.addExtension("xml");
723 wxmlFilter.addExtension("usr");
724 wxmlFilter.setDescription("Copernicus User Files");
725
726
727 // Starts the about dialog
728 willTankPanel.startDialog();
729
730 // Initialises to English.
731 updateLanguageTexts("GBR");
732
733
734 filter.addKeyListener(new java.awt.event.KeyListener() {
735 public void keyPressed(KeyEvent e) {
736 }
737 public void keyReleased(KeyEvent e) {
738 if (e.getKeyCode() == KeyEvent.VK_ENTER || filter.getText().equals("")) {
739 resortSiteList();
740 refreshSiteList();
741 }
742 }
743 public void keyTyped(KeyEvent e) {
744 }
745 });
746 KeyListener saveListener = new java.awt.event.KeyListener() {
747 public void keyPressed(KeyEvent e) {
748 saveNeeded();
749 }
750 public void keyReleased(KeyEvent e) {
751
752 }
753 public void keyTyped(KeyEvent e) {
754 }
755 };
756
757 username.addKeyListener(saveListener);
758 password.addKeyListener(saveListener);
759 comment.addKeyListener(saveListener);
760
761 /*
762 *
763 * KeyListeners to detect changes that need saving
764 *
765 */
766 {
767 passwordText.addKeyListener(new java.awt.event.KeyListener() {
768 public void keyPressed(KeyEvent e) {
769 }
770 public void keyReleased(KeyEvent e) {
771 keypressed_action(e);
772 }
773 public void keyTyped(KeyEvent e) {
774 }
775 });
776 usernameText.addKeyListener(new java.awt.event.KeyListener() {
777 public void keyPressed(KeyEvent e) {
778 }
779 public void keyReleased(KeyEvent e) {
780 keypressed_action(e);
781 }
782 public void keyTyped(KeyEvent e) {
783 }
784 });
785 commentText.addKeyListener(new java.awt.event.KeyListener() {
786 public void keyPressed(KeyEvent e) {
787 }
788 public void keyReleased(KeyEvent e) {
789 keypressed_action(e);
790 }
791 public void keyTyped(KeyEvent e) {
792 }
793 });
794 }
795
796 // Initialise
797 logout();
798
799
800 // Gets the program path.
801 File f = new File("");
802 baseDirectory = f.getAbsolutePath() + "/";
803
804
805 /*
806 * Settings
807 *
808 */
809
810 // Loads the language
811 changeLanguage(mainIni.getSectionAttributeStr("MAIN_SETTINGS", "language", "GBR"));
812
813
814 // Loads the users, note: 1000 user max.
815 for (int i = 0; i < 1000; i++) {
816
817 // Gets the filename of the user
818 String userToAdd = mainIni.getSectionAttributeStr("MAIN_SETTINGS", "user" + i, null);
819
820 if (userToAdd != null) {
821 // Adds the user (if exists)
822 users.add(userToAdd);
823
824 lastUser = i;
825 String userfilenamestr = userToAdd;
826
827 // Gets the display name name of the user
828 String usersName = mainIni.getSectionAttributeStr("MAIN_SETTINGS", "user_" + userfilenamestr+ "_name", userfilenamestr);
829
830 // Adds real name and filename to lookup tables
831 users_name.put(usersName, userfilenamestr);
832 users_filename.put(userfilenamestr, usersName);
833 }
834 }
835
836
837 populateUsersList();
838
839 //try to load the default user
840 String firstUser = mainIni.getSectionAttributeStr("MAIN_SETTINGS", "startingUser", null);
841
842
843
844 if (firstUser != null) {
845 loadUser(firstUser);
846 } else if (mainIni.getSectionAttributeBool("MAIN_SETTINGS", "newuser", true)) {
847
848
849 newUser();
850
851 //TODO create a new user.
852 System.out.println("NEW USER!");
853 } else {
854 logout();
855 }
856
857
858
859 lastLoadedFile = baseDirectory;
860
861 this.addWindowListener(new WindowAdapter() {
862 public void windowClosing(WindowEvent e) {
863 exitCopernicus();
864 }
865 });
866
867
868
869 setBounds(50,50,390,280);
870 int fw = (int) ((double) (Toolkit.getDefaultToolkit().getScreenSize().width - getWidth()) / 2.0);
871 int fh = (int) ((double) (Toolkit.getDefaultToolkit().getScreenSize().height - getHeight()) / 2.0);
872 if (fw < 0)
873 fw = 0;
874 if (fh < 0)
875 fh = 0;
876 setLocation(fw,fh);
877
878 setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE);
879
880 setVisible(true);
881
882 if (System.getProperty("DEBUG", "false").equalsIgnoreCase("true")) {
883 lingual.dumpRegisteredComponents();
884 }
885 }
886
887
888 /**
889 * Fired when a site is selected
890 *
891 */
892 public void siteSelected() {
893
894 int oldSelSite = selSite;
895 WXMLSection oldSite = lastSite;
896 if (siteList.getSelectedIndex() != -1 && sites.length != 0)
897 selSite = siteList.getSelectedIndex();
898 try {
899
900 lastSite = sites[selSite];
901 } catch (ArrayIndexOutOfBoundsException e) {
902
903 }
904 if (selSite < 0)
905 selSite = 0;
906 if (selSite > sites.length)
907 selSite = selSite -1;
908 if (sites.length == 0)
909 return;
910
911 if (oldSelSite != selSite && oldSite != lastSite) {
912 selLogin = 0;
913 refreshLoginList();
914
915 refreshCurrentLogin();
916 }
917 }
918
919 public void resortSiteList () {
920 sites = currentUser.getSubSection("dpass").getSubSectionGroup("site");
921
922 /*
923 * O(n^2) Selection Sort
924 */
925 for (int i = 0; i < sites.length; i++) {
926 for (int k = i+1; k < sites.length; k++) {
927 if (((String) sites[k].getAttributeValue("name")).compareToIgnoreCase((String) sites[i].getAttributeValue("name")) < 0 ) {
928 WXMLSection tmp = sites[i];
929 sites[i] = sites[k];
930 sites[k] = tmp;
931 } else {
932 }
933 }
934 }
935
936 /*
937 * Filter
938 */
939 WXMLSection sites2 [] = new WXMLSection [sites.length];
940 int count = 0;
941 for (int i = 0; i < sites.length; i++) {
942 try {
943 //if (((String) sites[i].getAttributeValue("name").substring(0, (filter.getText()).length())).equalsIgnoreCase(filter.getText())) {
944 if (sites[i].getAttributeValue("name").toUpperCase().indexOf(filter.getText().toUpperCase()) != -1) {
945
946 sites2[count] = sites[i];
947 count++;
948 }
949 } catch (StringIndexOutOfBoundsException e) {
950
951 }
952 }
953
954
955
956 sites = new WXMLSection [count];
957 for (int i = 0; i < count; i++) {
958 sites[i] = sites2[i];
959 }
960
961
962 }
963
964 public void refreshSiteList() {
965 Object [] listData = new Object [sites.length];
966 for (int i = 0; i < sites.length; i++) {
967 listData[i] = (String) sites[i].getAttributeValue("name");
968 }
969 siteList.setListData(listData);
970 selSite = -1;
971 }
972
973 public void loginSelected() {
974 //saveCurrentLogin();
975
976 int selected = accList.getSelectedIndex();
977 if (selected < 0) {
978 return;
979 }
980
981 selLogin = selected;
982
983 refreshCurrentLogin();
984 }
985
986 public void refreshCurrentLogin() {
987 if (lastLogin != null)
988 saveCurrentLogin();
989
990 username.setText(logins[selLogin].getAttributeValue("username"));
991 password.setText(logins[selLogin].getAttributeValue("pass"));
992 comment.setText(logins[selLogin].getAttributeValue("comment"));
993
994 lastLogin = logins[selLogin];
995 }
996
997 public void saveLogin() {
998 saveCurrentLogin();
999 }
1000
1001 public void saveCurrentLogin() {
1002 if (lastLogin == null) {
1003 return;
1004 }
1005 if (!lastLogin.getAttributeValue("username").equals(username.getText())) {
1006 lastLogin.setAttributeValue("username", username.getText());
1007 saveNeeded();
1008 }
1009 if (!lastLogin.getAttributeValue("pass").equals(password.getText())) {
1010 lastLogin.setAttributeValue("pass", password.getText());
1011 saveNeeded();
1012 }
1013 if (!lastLogin.getAttributeValue("comment").equals(comment.getText())) {
1014 lastLogin.setAttributeValue("comment", comment.getText());
1015 saveNeeded();
1016 }
1017
1018
1019 }
1020
1021 public boolean closeUser () {
1022
1023 saveCurrentLogin();
1024 if (saveConfirm) {
1025
1026 int result = JOptionPane.showConfirmDialog(this, lingual.translateWord( "Do you want to save the current user first") + "?", "Save Current User?", JOptionPane.YES_NO_CANCEL_OPTION);
1027 if (result == JOptionPane.YES_OPTION) {
1028 this.save_actionPerformed(null);
1029 } else if (result == JOptionPane.CANCEL_OPTION) {
1030 return false;
1031 }
1032 }
1033 saveConfirm = false;
1034 return true;
1035 //closed.
1036 }
1037
1038 public void saveUser() {
1039 saveCurrentLogin();
1040 saveConfirm = false;
1041 }
1042
1043 public void refreshLoginList() {
1044 try {
1045 accList.removeAllItems();
1046 logins = lastSite.getSubSectionGroup("login");
1047 for (int i=0; i < logins.length; i++) {
1048 accList.addItem(lastSite.getAttributeValue("name") + ": " + logins[i].getAttributeValue("userid"));
1049 }
1050 } catch (NullPointerException e) {
1051 return;
1052 }
1053
1054 if (logins.length > 1) {
1055 nextAccountButton.setEnabled(true);
1056 } else {
1057 nextAccountButton.setEnabled(false);
1058 }
1059 }
1060
1061 public void showHelpURL () {
1062 try {
1063 BrowserLauncher.openURL("http://tanksoftware.com/copernicus/docs/");
1064 } catch (IOException e) {
1065 JOptionPane.showMessageDialog(this, lingual.translateWord( "Please visit http://tanksoftware.com/copernicus/ to access the user documentation."), "Help", JOptionPane.OK_OPTION);
1066 }
1067 }
1068
1069 public void exitCopernicus () {
1070 this.setVisible(true);
1071 if (closeUser()) {
1072 System.exit(0);
1073 } else {
1074 this.setVisible(true);
1075 }
1076 }
1077
1078 public void renameSite() {
1079 String newSiteText = JOptionPane.showInputDialog(lingual.translateWord( "Please enter new site name"),lastSite.getAttributeValue("name"));
1080
1081 if (newSiteText == null || newSiteText.equals(""))
1082 return;
1083
1084 if (!lastSite.getAttributeValue("name").equals(newSiteText)) {
1085 lastSite.setAttributeValue("name", newSiteText);
1086 }
1087
1088 refreshSiteList();
1089 siteList.setSelectedIndex(selSite);
1090
1091 saveNeeded();
1092 }
1093
1094 public void renameLogin() {
1095 int oldSelLogin = selLogin;
1096 String newLoginText = JOptionPane.showInputDialog(lingual.translateWord( "Please enter new login name"),logins[selLogin].getAttributeValue("userid"));
1097
1098 if (newLoginText == null || newLoginText.equals(""))
1099 return;
1100
1101
1102 if (!logins[selLogin].getAttributeValue("userid").equals(newLoginText)) {
1103 logins[selLogin].setAttributeValue("userid", newLoginText);
1104 }
1105
1106 refreshLoginList();
1107
1108 selLogin = oldSelLogin;
1109 accList.setSelectedIndex(selLogin);
1110
1111 saveNeeded();
1112
1113
1114 }
1115
1116 public void deleteSite() {
1117 if (sites.length == 1 && filter.getText().equals("")) {
1118 JOptionPane.showMessageDialog(this, lingual.translateWord( "You can't delete the last Site"), "Reading Error.", JOptionPane.OK_OPTION);
1119 return;
1120 }
1121
1122 if (sites.length == 0 || sites.length == 1) {
1123 filter.setText("");
1124 }
1125
1126 currentUser.getSubSection("dpass").removeSubSection(lastSite);
1127
1128 if (!(selSite < sites.length-1))
1129 selSite--;
1130
1131 resortSiteList();
1132 refreshSiteList();
1133 if (!(selSite < sites.length))
1134 selSite--;
1135
1136 siteList.ensureIndexIsVisible(selSite);
1137 siteList.setSelectedIndex(selSite);
1138 refreshLoginList();
1139 selLogin = 0;
1140 refreshCurrentLogin();
1141
1142 saveNeeded();
1143 }
1144
1145 public void deleteLogin() {
1146 if (logins.length == 1) {
1147 JOptionPane.showMessageDialog(this, lingual.translateWord( "You can't delete the last Account"), "Reading Error.", JOptionPane.OK_OPTION);
1148 return;
1149 }
1150
1151 lastSite.removeSubSection(logins[selLogin]);
1152 int oldSelLogin = selLogin;
1153 refreshLoginList();
1154 if (oldSelLogin == logins.length)
1155 oldSelLogin = oldSelLogin -1;
1156 accList.setSelectedIndex(oldSelLogin);
1157 refreshCurrentLogin();
1158
1159 saveNeeded();
1160 }
1161
1162 public void addNewSite() {
1163 String newSiteText = JOptionPane.showInputDialog(lingual.translateWord( "Please enter new site name") + " (eg. www.hotmail.com).");
1164 if (newSiteText != null && !newSiteText.equals("")) {
1165 filter.setText("");
1166 createNewSite(newSiteText);
1167 resortSiteList();
1168 refreshSiteList();
1169 selSite = 0;
1170 for (int i = 0; i < sites.length; i++) {
1171 if (newSiteText.equals(sites[i].getAttributeValue("name"))) {
1172 siteList.ensureIndexIsVisible(i);
1173 siteList.setSelectedIndex(i);
1174 }
1175 }
1176 refreshLoginList();
1177 selLogin = 0;
1178 refreshCurrentLogin();
1179 }
1180 username.grabFocus();
1181 saveNeeded();
1182 }
1183 public void nextLogin() {
1184 selLogin = selLogin + 1;
1185 selLogin = selLogin % logins.length;
1186 accList.setSelectedIndex(selLogin);
1187 refreshCurrentLogin();
1188
1189
1190 }
1191 public void addNewLogin() {
1192 String newLoginText = JOptionPane.showInputDialog(lingual.translateWord( "Please the title for your login") + " (eg. \"secondary account\").");
1193 if (newLoginText != null && !newLoginText.equals("")) {
1194 WXMLSection newSection = new WXMLSection("login", lastSite);
1195 newSection.addAttribute(new WXMLSection.WXMLAttribute("userid", newLoginText, true));
1196 newSection.addAttribute(new WXMLSection.WXMLAttribute("username", "", true));
1197 newSection.addAttribute(new WXMLSection.WXMLAttribute("pass", "", true));
1198 newSection.addAttribute(new WXMLSection.WXMLAttribute("comment", "", true));
1199 lastSite.addSubSection(newSection);
1200
1201 refreshLoginList();
1202 accList.setSelectedIndex(logins.length-1);
1203
1204 }
1205
1206 username.grabFocus();
1207
1208 saveNeeded();
1209 }
1210
1211
1212 public void saveNeeded() {
1213
1214 saveConfirm = true;
1215 }
1216
1217 /**
1218 * Runs Copernicus. Currently command line arguments are ignored
1219 *
1220 *@param args Any command line arguments.
1221 */
1222 public static void main(String[] args) {
1223 new Copernicus();
1224 }
1225
1226
1227
1228 /**
1229 * Logs off a user.
1230 *
1231 */
1232 private void logout () {
1233 checkLoginChanged(true);
1234
1235 if (currentUser != null) {
1236 if (!closeUser()) {
1237 return;
1238 }
1239 }
1240
1241
1242
1243 currentUser = null;
1244 currentSite = null;
1245 currentLogin = null;
1246 currentUserFileName = null;
1247
1248 for (int i = 0; i < componentEnableList.size(); i++) {
1249 JComponent c = (JComponent) componentEnableList.get(i);
1250 c.setEnabled(false);
1251 }
1252
1253 setTitle("Copernicus - (no user loaded)");
1254
1255 this.getContentPane().removeAll();
1256 this.repaint();
1257
1258 saveConfirm = false;
1259
1260 }
1261
1262 /**
1263 * Loads a given user. If the load "fails" without encryption, then it is retried with encryption.
1264 *
1265 *@param filename the user file to load.
1266 */
1267 private void loadUser (String filename) {
1268
1269
1270
1271 if (currentUser != null)
1272 if (!closeUser())
1273 return;
1274
1275 filter.setText("");
1276
1277
1278 // Logs out the current user.
1279 logout();
1280
1281 System.out.println("Loading user file: " + filename);
1282 repaint();
1283
1284 /*
1285 * Read file contents
1286 */
1287 String fileContents = null;
1288
1289 try {
1290 fileContents = FileUtil.getContents(FileUtil.getFileSpecificBufferedReader(filename));
1291
1292 } catch (IOException ex) {
1293 JOptionPane.showMessageDialog(null, lingual.translateWord( "Error Reading File") + ": " + filename + ". " + lingual.translateWord( "Probable bad file (missing or unavailible)") + ".", "Reading Error.", JOptionPane.OK_OPTION);
1294 logout();
1295 fileContents = null;
1296 }
1297
1298 if (fileContents != null) {
1299 //String fileContents = currentFile.getFileContents();
1300
1301 try {
1302
1303 //Try to load the file without encrypting
1304 currentUser = WXML.parseString(fileContents);
1305 WXMLSection test = currentUser.getSubSection("dpass");
1306 this.useEncryption.setSelected(false);
1307 this.mUseEncryption.setSelected(false);
1308 if (currentUser == null || test == null)
1309 throw new NullPointerException ();
1310
1311 } catch (Exception e) {
1312
1313
1314 //that failed, so now try to decrypt it
1315 try {
1316 String password = JOptionPane.showInputDialog(lingual.translateWord( "The file") + " " + filename + " " + lingual.translateWord( "appears to be encrypted. Please enter a password."));
1317
1318 //Generate key from password
1319 String key = OneTimeNOCList.generateRandomKey(fileContents, password, 0);
1320
1321 //decrypt
1322 BufferedReader brKey = new BufferedReader(new StringReader(key));
1323 BufferedReader brEncrypted = new BufferedReader(new StringReader(fileContents));
1324 StringWriter plainText = new StringWriter ();
1325 BufferedWriter bwPlain = new BufferedWriter(plainText);
1326
1327 try {
1328 OneTimeNOCList.decrypt(bwPlain, brEncrypted, brKey);
1329 this.useEncryption.setSelected(true);
1330 this.mUseEncryption.setSelected(true);
1331 } catch (IOException ex) {
1332 }
1333
1334 try {
1335 currentUser = WXML.parseString(plainText.toString());
1336 WXMLSection test = currentUser.getSubSection("dpass");
1337 if (test == null)
1338 throw new NullPointerException ();
1339 } catch (Exception ex) {
1340
1341 JOptionPane.showMessageDialog(null, lingual.translateWord( "Error Reading File. Possible Incorrect Password or invalid file."), "Reading Error.", JOptionPane.OK_OPTION);
1342 throw new NullPointerException ();
1343 }
1344
1345 //try to decrypt
1346 } catch (NullPointerException exp) {
1347
1348 // Bad password or bad file. Bad file could be ill-formatted or
1349 // corrupted, or non-existant.
1350 logout();
1351 currentUser = null;
1352 }
1353 }
1354
1355 currentUserFileName = filename;
1356
1357 } else {
1358 currentUser = null;
1359 }
1360
1361 reloadCurrentUser();
1362
1363 if (currentUser != null) {