c3448da41dcd29be888b390287de7e6dce7f9299
[debian/jabref.git] / src / java / net / sf / jabref / JabRef.java
1 /*
2  * Copyright (C) 2003 Morten O. Alver, Nizar N. Batada
3  * 
4  * All programs in this directory and subdirectories are published under the GNU
5  * General Public License as described below.
6  *
7  * This program is free software; you can redistribute it and/or modify it under
8  * the terms of the GNU General Public License as published by the Free Software
9  * Foundation; either version 2 of the License, or (at your option) any later
10  * version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
15  * details.
16  *
17  * You should have received a copy of the GNU General Public License along with
18  * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19  * Place, Suite 330, Boston, MA 02111-1307 USA
20  *
21  * Further information about the GNU GPL is available at:
22  * http://www.gnu.org/copyleft/gpl.ja.html
23  *
24  */
25 package net.sf.jabref;
26
27 import net.sf.jabref.export.*;
28 import net.sf.jabref.imports.*;
29 import net.sf.jabref.wizard.auximport.*;
30 import net.sf.jabref.remote.RemoteListener;
31
32 import gnu.dtools.ritopt.*;
33 import java.awt.*;
34 import java.awt.event.KeyEvent;
35
36 import java.io.*;
37 import java.io.File;
38
39 import java.util.*;
40 import java.util.List;
41 import java.lang.reflect.Method;
42 import java.lang.reflect.InvocationTargetException;
43
44 import javax.swing.*;
45 import javax.swing.plaf.metal.MetalLookAndFeel;
46
47 import com.jgoodies.looks.plastic.Plastic3DLookAndFeel;
48 import com.jgoodies.looks.plastic.PlasticLookAndFeel;
49 import com.jgoodies.looks.windows.WindowsLookAndFeel;
50 import com.jgoodies.looks.FontSet;
51 import com.jgoodies.looks.FontSets;
52 import com.jgoodies.looks.FontPolicy;
53 import com.jgoodies.looks.FontPolicies;
54
55 //import javax.swing.UIManager;
56 //import javax.swing.UIDefaults;
57 //import javax.swing.UnsupportedLookAndFeelException;
58 public class JabRef {
59     public static JabRef ths;
60     public static RemoteListener remoteListener = null;
61     public JabRefFrame jrf;
62     public Options options;
63     public Frame splashScreen = null;
64
65     boolean graphicFailure = false;
66
67     StringOption importFile, exportFile, exportPrefs, importPrefs, auxImExport, importToOpenBase;
68     BooleanOption helpO, disableGui, blank, loadSess, showVersion;
69     /*
70     * class StringArrayOption extends ArrayOption { public public void
71     * modify(String value) { } public void modify(String[] value) { } public
72     * Object[] getObjectArray() { return null; } public String getTypeName() {
73     * return "Strings"; } public String getStringValue() { return ""; } public
74     * Object getObject() { return null; } }
75     */
76     public static void main(String[] args) {
77         new JabRef(args);
78     }
79
80     public JabRef(String[] args) {
81
82         ths = this;
83         JabRefPreferences prefs = JabRefPreferences.getInstance();
84         Globals.prefs = prefs;
85         Globals.setLanguage(prefs.get("language"), "");
86                 
87         Globals.importFormatReader.resetImportFormats();
88         BibtexEntryType.loadCustomEntryTypes(prefs);
89         // Build the list of available export formats:
90         ExportFormats.initAllExports();
91
92         // Read list(s) of journal names and abbreviations:
93         //Globals.turnOnFileLogging();
94
95         Globals.initializeJournalNames();
96
97         if (Globals.prefs.getBoolean("useRemoteServer")) {
98             remoteListener = RemoteListener.openRemoteListener(this);
99             if (remoteListener != null) {
100                 remoteListener.start();
101             }
102
103         // Unless we are alone, try to contact already running JabRef:
104             if (remoteListener == null) {
105                     if (RemoteListener.sendToActiveJabRefInstance(args)) {
106                 // We have successfully sent our command line options through the socket to
107                 // another JabRef instance. So we assume it's all taken care of, and quit.
108                 System.out.println(Globals.lang("Arguments passed on to running JabRef instance. Shutting down."));
109                 System.exit(0);
110             }
111         }
112         }
113
114       /**
115        * See if the user has a personal journal list set up. If so, add these
116        * journal names and abbreviations to the list:
117        */
118       String personalJournalList = prefs.get("personalJournalList");
119       if (personalJournalList != null) {
120           try {
121               Globals.journalAbbrev.readJournalList(new File(personalJournalList));
122           } catch (FileNotFoundException e) {
123               e.printStackTrace();
124           }
125       }
126
127         
128         //System.setProperty("sun.awt.noerasebackground", "true");
129         
130         //System.out.println(java.awt.Toolkit.getDefaultToolkit().getDesktopProperty("awt.dynamicLayoutSupported"));
131         // Make sure of a proper cleanup when quitting (e.g. deleting temporary
132         // files).
133         System.runFinalizersOnExit(true);
134
135         Vector loaded = processArguments(args, true);
136         openWindow(loaded);
137         //System.out.println("1");
138     }
139
140     private void setupOptions() {
141
142         importFile = new StringOption("");
143         exportFile = new StringOption("");
144         helpO = new BooleanOption();
145         disableGui = new BooleanOption();
146         blank = new BooleanOption();
147         loadSess = new BooleanOption();
148         showVersion = new BooleanOption();
149         exportPrefs = new StringOption("jabref_prefs.xml");
150         importPrefs = new StringOption("jabref_prefs.xml");
151         auxImExport = new StringOption("");
152         importToOpenBase = new StringOption("");
153
154         options = new Options("JabRef "); // Create an options repository.
155         options.setVersion(GUIGlobals.version);
156
157         importFile.setDescription("imopoepuoeu"); //Globals.lang);
158         options.register("version", 'v',
159                 Globals.lang("Display version"), showVersion);
160         options.register("nogui", 'n',
161             Globals.lang("No GUI. Only process command line options."), disableGui);
162         options.register("import", 'i',
163             Globals.lang("Import file") + ": " + Globals.lang("filename")
164             + "[,import format]", importFile);
165         options.register("output", 'o',
166             Globals.lang("Output or export file") + ": " + Globals.lang("filename")
167             + "[,export format]", exportFile);
168         options.register("help", 'h',
169             Globals.lang("Display help on command line options"), helpO);
170         options.register("loads", 'l', Globals.lang("Load session"), loadSess);
171         options.register("prexp", 'x', Globals.lang("Export preferences to file"),
172             exportPrefs);
173         options.register("primp", 'p', Globals.lang("Import preferences from file"),
174             importPrefs);
175         options.register("aux", 'a',
176             Globals.lang("Subdatabase from aux") + ": " + Globals.lang("file")+"[.aux]" + ","+Globals.lang("new")+"[.bib]",
177             auxImExport);
178         options.register("blank", 'b', Globals.lang("Do not open any files at startup"), blank);
179
180         options.register("importToOpen", '\0', Globals.lang("Import to open tab"), importToOpenBase);
181
182         options.setUseMenu(false);
183     }
184
185     public Vector processArguments(String[] args, boolean initialStartup) {
186
187         setupOptions();
188         String[] leftOver = options.process(args);
189
190
191
192         //Util.pr(": Options processed");
193
194         if (initialStartup && showVersion.isInvoked()) {
195             options.displayVersion();
196             disableGui.setInvoked(true);
197         }
198
199         if (initialStartup && helpO.isInvoked()) {
200             System.out.println("jabref [options] [bibtex-file]\n");
201             System.out.println(options.getHelp());
202
203             String importFormats = Globals.importFormatReader.getImportFormatList();
204             System.out.println(Globals.lang("Available import formats") + ":\n"
205                 + importFormats);
206
207             String outFormats = ExportFormats.getConsoleExportList(70, 20, "\t");
208             System.out.println(Globals.lang("Available export formats") + ": " + outFormats
209                 + ".");
210             System.exit(0);
211         }
212
213         // First we quickly scan the command line parameters for any that signal
214         // that the GUI
215         // should not be opened. This is used to decide whether we should show the
216         // splash screen or not.
217         if (initialStartup && !disableGui.isInvoked()) {
218             try {
219
220                 splashScreen = SplashScreen.splash();
221
222             } catch (Throwable ex) {
223                 graphicFailure = true;
224                 System.err.println(Globals.lang("Unable to create graphical interface")
225                     + ".");
226             }
227         }
228
229         //Util.pr("JabRef "+GUIGlobals.version);
230         // Vector to put imported/loaded database(s) in.
231         Vector loaded = new Vector();
232         Vector toImport = new Vector();
233         if (!blank.isInvoked() && (leftOver.length > 0))  {
234             for (int i = 0; i < leftOver.length; i++) {
235                 // Leftover arguments that have a "bib" extension are interpreted as
236                 // bib files to open. Other files, and files that could not be opened
237                 // as bib, we try to import instead.
238                 boolean bibExtension = leftOver[i].toLowerCase().endsWith("bib");
239                 ParserResult pr = null;
240                 if (bibExtension)
241                     pr = openBibFile(leftOver[i]);
242
243                 if ((pr == null) || (pr == ParserResult.INVALID_FORMAT)) {
244                     // We will try to import this file. Normally we
245                     // will import it into a new tab, but if this import has
246                     // been initiated by another instance through the remote
247                     // listener, we will instead import it into the current database.
248                     // This will enable easy integration with web browers that can
249                     // open a reference file in JabRef.
250                     if (initialStartup) {
251                         toImport.add(leftOver[i]);
252                     } else {
253                         ParserResult res = importToOpenBase(leftOver[i]);
254                         if (res != null)
255                             loaded.add(res);
256                     }
257                 }
258                 else
259                     loaded.add(pr);
260
261             }
262         }
263
264         //Util.pr(": Checked blank");
265
266         if (!blank.isInvoked() && importFile.isInvoked()) {
267             toImport.add(importFile.getStringValue());
268         }
269
270         if (toImport.size() > 0) for (int i = 0; i < toImport.size(); i++) {
271             String[] data = ((String) toImport.elementAt(i)).split(",");
272
273             try {
274
275                 if ((data.length > 1) && !"*".equals(data[1])) {
276                     System.out.println(Globals.lang("Importing") + ": " + data[0]);
277                     List entries =
278                             Globals.importFormatReader.importFromFile(data[1],
279                                     data[0].replaceAll("~", System.getProperty("user.home")));
280                     BibtexDatabase base = ImportFormatReader.createDatabase(entries);
281                     ParserResult pr = new ParserResult(base, null, new HashMap());
282                     loaded.add(pr);
283
284                 } else {
285                     // * means "guess the format":
286                     System.out.println(Globals.lang("Importing in unknown format")
287                             + ": " + data[0]);
288
289                     Object[] o =
290                             Globals.importFormatReader.importUnknownFormat(data[0]
291                                     .replaceAll("~", System.getProperty("user.home")));
292                     String formatName = (String) o[0];
293
294                     if (formatName == null) {
295                         System.err.println(Globals.lang("Error opening file") + " '" + data[0] + "'");
296                     } else if (formatName.equals(ImportFormatReader.BIBTEX_FORMAT)) {
297                         ParserResult pr = (ParserResult) o[1];
298                         loaded.add(pr);
299
300                     } else {
301                         List entries = (java.util.List) o[1];
302                         if (entries != null)
303                             System.out.println(Globals.lang("Format used") + ": "
304                                     + formatName);
305                         else
306                             System.out.println(Globals.lang(
307                                     "Could not find a suitable import format."));
308
309                         if (entries != null) {
310                             BibtexDatabase base = ImportFormatReader.createDatabase(entries);
311                             ParserResult pr = new ParserResult(base, null, new HashMap());
312
313                             //pr.setFile(new File(data[0]));
314                             loaded.add(pr);
315                         }
316                     }
317                 }
318             } catch (IOException ex) {
319                 System.err.println(Globals.lang("Error opening file") + " '"
320                         + data[0] + "': " + ex.getMessage());
321             }
322
323
324         }
325
326
327         if (!blank.isInvoked() && importToOpenBase.isInvoked()) {
328             ParserResult res = importToOpenBase(importToOpenBase.getStringValue());
329             if (res != null)
330                 loaded.add(res);
331         }
332
333         if (exportFile.isInvoked()) {
334             if (loaded.size() > 0) {
335                 String[] data = exportFile.getStringValue().split(",");
336
337                 if (data.length == 1) {
338                     // This signals that the latest import should be stored in BibTeX
339                     // format to the given file.
340                     if (loaded.size() > 0) {
341                         ParserResult pr =
342                             (ParserResult) loaded.elementAt(loaded.size() - 1);
343
344                         try {
345                             System.out.println(Globals.lang("Saving") + ": " + data[0]);
346                             SaveSession session = FileActions.saveDatabase(pr.getDatabase(),
347                                 new MetaData(pr.getMetaData(),pr.getDatabase()), new File(data[0]), Globals.prefs,
348                                 false, false, Globals.prefs.get("defaultEncoding"));
349                             // Show just a warning message if encoding didn't work for all characters:
350                             if (!session.getWriter().couldEncodeAll())
351                                 System.err.println(Globals.lang("Warning")+": "+
352                                     Globals.lang("The chosen encoding '%0' could not encode the following characters: ",
353                                     session.getEncoding())+session.getWriter().getProblemCharacters());
354                             session.commit();
355                         } catch (SaveException ex) {
356                             System.err.println(Globals.lang("Could not save file") + " '"
357                                 + data[0] + "': " + ex.getMessage());
358                         }
359                     } else
360                         System.err.println(Globals.lang(
361                                 "The output option depends on a valid import option."));
362                 } else if (data.length == 2) {
363                     // This signals that the latest import should be stored in the given
364                     // format to the given file.
365                     ParserResult pr = (ParserResult) loaded.elementAt(loaded.size() - 1);
366                     System.out.println(Globals.lang("Exporting") + ": " + data[0]);
367                     ExportFormat format = ExportFormats.getExportFormat(data[1]);
368                     if (format != null) {
369                         // We have an ExportFormat instance:
370                         try {
371                             format.performExport(pr.getDatabase(), data[0], pr.getEncoding(), null);
372                         } catch (Exception ex) {
373                             System.err.println(Globals.lang("Could not export file")
374                                 + " '" + data[0] + "': " + ex.getMessage());
375                         }
376                     }
377                     else
378                         System.err.println(Globals.lang("Unknown export format")
379                                 + ": " + data[1]);
380
381                 }
382             } else
383                 System.err.println(Globals.lang(
384                         "The output option depends on a valid import option."));
385         }
386
387         //Util.pr(": Finished export");
388
389         if (exportPrefs.isInvoked()) {
390             try {
391                 Globals.prefs.exportPreferences(exportPrefs.getStringValue());
392             } catch (IOException ex) {
393                 Util.pr(ex.getMessage());
394             }
395         }
396
397
398         if (importPrefs.isInvoked()) {
399             try {
400                 Globals.prefs.importPreferences(importPrefs.getStringValue());
401                 BibtexEntryType.loadCustomEntryTypes(Globals.prefs);
402             }
403             catch (IOException ex) {
404                 Util.pr(ex.getMessage());
405             }
406         }
407
408         if (!blank.isInvoked() && auxImExport.isInvoked()) {
409             boolean usageMsg = false;
410
411             if (loaded.size() > 0) // bibtex file loaded
412              {
413                 String[] data = auxImExport.getStringValue().split(",");
414
415                 if (data.length == 2) {
416                     ParserResult pr = (ParserResult) loaded.firstElement();
417                     AuxCommandLine acl = new AuxCommandLine(data[0], pr.getDatabase());
418                     BibtexDatabase newBase = acl.perform();
419
420                     boolean notSavedMsg = false;
421
422                     // write an output, if something could be resolved
423                     if (newBase != null) {
424                         if (newBase.getEntryCount() > 0) {
425                             String subName = Util.getCorrectFileName(data[1], "bib");
426
427                             try {
428                                 System.out.println(Globals.lang("Saving") + ": "
429                                     + subName);
430                                 SaveSession session = FileActions.saveDatabase(newBase, new MetaData(), // no Metadata
431                                     new File(subName), Globals.prefs, false, false,
432                                     Globals.prefs.get("defaultEncoding"));
433                                 // Show just a warning message if encoding didn't work for all characters:
434                                 if (!session.getWriter().couldEncodeAll())
435                                     System.err.println(Globals.lang("Warning")+": "+
436                                         Globals.lang("The chosen encoding '%0' could not encode the following characters: ",
437                                         session.getEncoding())+session.getWriter().getProblemCharacters());
438                                 session.commit();
439                             } catch (SaveException ex) {
440                                 System.err.println(Globals.lang("Could not save file")
441                                     + " '" + subName + "': " + ex.getMessage());
442                             }
443
444                             notSavedMsg = true;
445                         }
446                     }
447
448                     if (!notSavedMsg)
449                         System.out.println(Globals.lang("no database generated"));
450                 } else
451                     usageMsg = true;
452             } else
453                 usageMsg = true;
454
455             if (usageMsg) {
456                 System.out.println(Globals.lang("no base-bibtex-file specified"));
457                 System.out.println(Globals.lang("usage") + " :");
458                 System.out.println(
459                     "jabref --aux infile[.aux],outfile[.bib] base-bibtex-file");
460             }
461         }
462
463         return loaded;
464     }
465
466     ParserResult importFiletypeUnknown(String fname) {
467         Object[] o =
468                 Globals.importFormatReader.importUnknownFormat(fname
469                         .replaceAll("~", System.getProperty("user.home")));
470         String formatName = (String) o[0];
471
472         if (formatName == null) {
473             System.err.println(Globals.lang("Error opening file") + " '" + fname + "'");
474         } else if (formatName.equals(ImportFormatReader.BIBTEX_FORMAT)) {
475             ParserResult pr = (ParserResult) o[1];
476             return pr;
477         } else {
478             List entries = (java.util.List) o[1];
479             if (entries != null)
480                 System.out.println(Globals.lang("Format used") + ": "
481                         + formatName);
482             else
483                 System.out.println(Globals.lang(
484                         "Could not find a suitable import format."));
485
486             if (entries != null) {
487                 BibtexDatabase base = ImportFormatReader.createDatabase(entries);
488                 ParserResult pr = new ParserResult(base, null, new HashMap());
489                 return pr;
490             }
491         }
492         
493         // not reached
494         return null;
495     }
496
497     public void openWindow(Vector loaded) {
498         if (!graphicFailure && !disableGui.isInvoked()) {
499             // Call the method performCompatibilityUpdate(), which does any
500             // necessary changes for users with a preference set from an older
501             // Jabref version.
502             Util.performCompatibilityUpdate();
503
504             // Set up custom or default icon theme:
505             GUIGlobals.setUpIconTheme();
506
507            // This property is set to make the Mac OSX Java VM move the menu bar to
508             // the top
509             // of the screen, where Mac users expect it to be.
510             System.setProperty("apple.laf.useScreenMenuBar", "true");
511
512             // Set antialiasing on everywhere. This only works in JRE >= 1.5.
513             // Or... it doesn't work, period.
514             //System.setProperty("swing.aatext", "true");
515             // If we are not on Mac, deal with font sizes and LookAndFeels:
516             if (!Globals.ON_MAC) {
517                 int fontSizes = Globals.prefs.getInt("menuFontSize");
518                 boolean overrideDefaultFonts = Globals.prefs.getBoolean("overrideDefaultFonts");
519                 String defaultLookAndFeel;
520
521                 if (Globals.ON_WIN)
522                     defaultLookAndFeel = GUIGlobals.windowsDefaultLookAndFeel;
523                 else
524                     defaultLookAndFeel = GUIGlobals.linuxDefaultLookAndFeel;
525
526                 String lookAndFeel = null;
527
528                 if (!Globals.prefs.getBoolean("useDefaultLookAndFeel"))
529                     lookAndFeel = Globals.prefs.get("lookAndFeel");
530                 else
531                     lookAndFeel = defaultLookAndFeel;
532
533                 LookAndFeel lnf = null;
534                 Object objLnf = null;
535
536
537                 try {
538                     if (lookAndFeel != null)
539                         objLnf = Class.forName(lookAndFeel).newInstance();
540                     else
541                         objLnf = Class.forName(defaultLookAndFeel).newInstance();
542                 } catch (Exception ex) {
543                     ex.printStackTrace();
544
545                     try {
546                         objLnf = Class.forName(defaultLookAndFeel).newInstance();
547                     } catch (Exception ex2) {
548                     }
549                 }
550
551                 if (objLnf != null)
552                     lnf = (LookAndFeel) objLnf;
553
554                 // Set font sizes if we are using a JGoodies look and feel.
555                 if ((lnf != null) && (lnf instanceof Plastic3DLookAndFeel)) {
556
557                     //UIManager.put("jgoodies.popupDropShadowEnabled", Boolean.TRUE);
558                     MetalLookAndFeel.setCurrentTheme(new
559                      com.jgoodies.looks.plastic.theme.SkyBluer());
560
561                     // Set a "model" icon size, so menu items are evenly spaced even though
562                     // only some items have icons. We load an arbitrary icon and look at
563                     // its size to determine what size to use:
564                     int defaultIconSize = GUIGlobals.getImage("open").getIconWidth();
565                     com.jgoodies.looks.Options.setDefaultIconSize
566                             (new Dimension(defaultIconSize, defaultIconSize));
567
568
569                     if (overrideDefaultFonts) {
570                         FontSet fontSet = FontSets.createDefaultFontSet(
571                             new Font("Tahoma", Font.PLAIN, fontSizes),    // control font
572                             new Font("Tahoma", Font.PLAIN, fontSizes),    // menu font
573                             new Font("Tahoma", Font.BOLD, fontSizes)     // title font
574                             );
575                         FontPolicy fixedPolicy = FontPolicies.createFixedPolicy(fontSet);
576                         Plastic3DLookAndFeel.setFontPolicy(fixedPolicy);
577                     }
578
579                     //Plastic3DLookAndFeel plLnf = (Plastic3DLookAndFeel) lnf;
580                 }
581                 else if ((lnf != null) && (lnf instanceof WindowsLookAndFeel)) {
582
583                     // Set a "model" icon size, so menu items are evenly spaced even though
584                     // only some items have icons. We load an arbitrary icon and look at
585                     // its size to determine what size to use:
586                     int defaultIconSize = GUIGlobals.getImage("open").getIconWidth();
587                     com.jgoodies.looks.Options.setDefaultIconSize
588                         (new Dimension(defaultIconSize, defaultIconSize));
589
590                     if (overrideDefaultFonts) {
591                         FontSet fontSet = FontSets.createDefaultFontSet(
592                             new Font("Tahoma", Font.PLAIN, fontSizes),    // control font
593                             new Font("Tahoma", Font.PLAIN, fontSizes),    // menu font
594                             new Font("Tahoma", Font.BOLD, fontSizes)     // title font
595                             );
596                         FontPolicy fixedPolicy = FontPolicies.createFixedPolicy(fontSet);
597                         WindowsLookAndFeel.setFontPolicy(fixedPolicy);
598                     }
599
600                     //WindowsLookAndFeel plLnf = (WindowsLookAndFeel) lnf;
601                 }
602
603                 if (lnf != null) {
604                     try {
605
606                         UIManager.setLookAndFeel(lnf);
607
608                         if (!Globals.ON_WIN) {
609                             UIManager.put("SimpleInternalFrame.activeTitleBackground", GUIGlobals.gradientBlue);
610                         }
611
612                         if (!Globals.ON_WIN && !Globals.ON_MAC) {
613                             // For Linux, add Enter as button click key:
614                             UIDefaults def = UIManager.getDefaults();
615                             InputMap im = (InputMap)def.get("Button.focusInputMap");
616                             im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false), "pressed");
617                             im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true), "released");
618                         }
619                     } catch (Throwable ex) {
620                         ex.printStackTrace();
621                         System.err.println("Trying to set system default Look&Feel...");
622
623                         // if desired lnf could not be set, try system default
624                         try {
625                             UIManager.setLookAndFeel(UIManager
626                                 .getSystemLookAndFeelClassName());
627                         } catch (Throwable e) {
628                             e.printStackTrace();
629                         }
630                     }
631
632                     //LookAndFeel lnf = new com.sun.java.swing.plaf.gtk.GTKLookAndFeel();
633                     //Look1AndFeel lnf = new
634                     // com.incors.plaf.kunststoff.KunststoffLookAndFeel();
635                     //com.incors.plaf.kunststoff.KunststoffLookAndFeel.setCurrentTheme(new
636                     // com.incors.plaf.kunststoff.themes.KunststoffDesktopTheme());
637                 }
638
639             }
640
641
642             // If the option is enabled, open the last edited databases, if any.
643             if (!blank.isInvoked() && Globals.prefs.getBoolean("openLastEdited") && (Globals.prefs.get("lastEdited") != null)) {
644                 // How to handle errors in the databases to open?
645                 String[] names = Globals.prefs.getStringArray("lastEdited");
646 lastEdLoop: 
647                 for (int i = 0; i < names.length; i++) {
648                     File fileToOpen = new File(names[i]);
649
650                     for (int j = 0; j < loaded.size(); j++) {
651                         ParserResult pr = (ParserResult) loaded.elementAt(j);
652
653                         if ((pr.getFile() != null) &&pr.getFile().equals(fileToOpen))
654                             continue lastEdLoop;
655                     }
656
657                     if (fileToOpen.exists()) {
658                         ParserResult pr = openBibFile(names[i]);
659
660                         if (pr != null) {
661
662                             if (pr == ParserResult.INVALID_FORMAT) {
663                                 System.out.println(Globals.lang("Error opening file")+" '"+fileToOpen.getPath()+"'");
664                             }
665                             else
666                                 loaded.add(pr);
667
668                         }
669                     }
670                 }
671             }
672
673             GUIGlobals.init();
674             GUIGlobals.CURRENTFONT =
675                 new Font(Globals.prefs.get("fontFamily"), Globals.prefs.getInt("fontStyle"),
676                     Globals.prefs.getInt("fontSize"));
677
678             //Util.pr(": Initializing frame");
679             jrf = new JabRefFrame();
680
681             // Add all loaded databases to the frame:
682             boolean first = true;
683             if (loaded.size() > 0) {
684                 for (Iterator i=loaded.iterator(); i.hasNext();) {
685                     ParserResult pr = (ParserResult)i.next();
686                     jrf.addTab(pr.getDatabase(), pr.getFile(), pr.getMetaData(), pr.getEncoding(), first);
687                     first = false;
688                 }
689             }
690
691             if (loadSess.isInvoked())
692                 jrf.loadSessionAction.actionPerformed(new java.awt.event.ActionEvent(
693                         jrf, 0, ""));
694
695             if (splashScreen != null) {// do this only if splashscreen was actually created
696                 splashScreen.dispose();
697                 splashScreen = null;
698             }
699
700             //Util.pr(": Showing frame");
701             jrf.setVisible(true);
702
703             // TEST TEST TEST TEST TEST TEST
704             startOOPlugin(jrf);
705
706             for (int i = 0; i < loaded.size(); i++) {
707                 ParserResult pr = (ParserResult) loaded.elementAt(i);
708                 if (Globals.prefs.getBoolean("displayKeyWarningDialogAtStartup") && pr.hasWarnings()) {
709                     String[] wrns = pr.warnings();
710                     StringBuffer wrn = new StringBuffer();
711                     for (int j = 0; j<wrns.length; j++)
712                         wrn.append(j + 1).append(". ").append(wrns[j]).append("\n");
713                     if (wrn.length() > 0)
714                         wrn.deleteCharAt(wrn.length() - 1);
715                     jrf.showBaseAt(i);
716                     JOptionPane.showMessageDialog(jrf, wrn.toString(),
717                         Globals.lang("Warnings"),
718                         JOptionPane.WARNING_MESSAGE);
719                 }
720             }
721
722             //Util.pr(": Finished adding panels");
723
724             if (loaded.size() > 0) {
725                 jrf.tabbedPane.setSelectedIndex(0);
726                 new FocusRequester(((BasePanel) jrf.tabbedPane.getComponentAt(0)).mainTable);
727             }
728         } else
729             System.exit(0);
730     }
731
732     /**
733      * Morten Alver (sept. 06): I'm adding this to run the functionality for
734      * OpenOffice integration. I'm not sure yet how to handle deployment issues,
735      * because the OO stuff requires several OO jars on the classpath, which we
736      * shouldn't distribute because OO installations already have them.
737      *
738      * To avoid introducing dependencies on these jars for the time being,
739      * I'm keeping OO "plugin" files separate, only invoking them through reflection.
740      *
741      * @param jrf The JabRefFrame.
742      */
743     private void startOOPlugin(JabRefFrame jrf) {
744
745
746         try {
747             Class c = Class.forName("net.sf.jabref.oo.OOTestPanel");
748             Method m = c.getDeclaredMethod("open",
749                     new Class[] {JabRefFrame.class});
750             Object i = c.newInstance();
751             Object r = m.invoke(i, new Object[] {jrf});
752         } catch (Exception e) {
753             // Do nothing.
754             //System.out.println("OO plugin not found.");
755             //e.printStackTrace();
756         }
757         
758     }
759
760     public static ParserResult openBibFile(String name) {
761         System.out.println(Globals.lang("Opening") + ": " + name);
762
763         try {
764             File file = new File(name);
765             String encoding = Globals.prefs.get("defaultEncoding");
766             ParserResult pr = OpenDatabaseAction.loadDatabase(file, encoding);
767             if (pr == null)
768                 return ParserResult.INVALID_FORMAT;
769             pr.setFile(file);
770             if (pr.hasWarnings()) {
771                 String[] warn = pr.warnings();
772                 for (int i=0; i<warn.length; i++)
773                     System.out.println(Globals.lang("Warning")+": "+warn[i]);
774
775             }
776             return pr;
777         } catch (Throwable ex) {
778             //System.err.println(Globals.lang("Error opening file")+" '"+ name+"':
779             // "+ex.getMessage());
780             System.err.println(Globals.lang("Error opening file") + ": "
781                 + ex.getMessage());
782         }
783
784         return null;
785     }
786
787     public static ParserResult importToOpenBase(String argument) {
788         String[] data = argument.split(",");
789         try {
790             if ((data.length > 1) && !"*".equals(data[1])) {
791                 System.out.println(Globals.lang("Importing") + ": " + data[0]);
792                 List entries =
793                     Globals.importFormatReader.importFromFile(data[1],
794                         data[0].replaceAll("~", System.getProperty("user.home")));
795                 BibtexDatabase base = ImportFormatReader.createDatabase(entries);
796                 ParserResult pr = new ParserResult(base, null, new HashMap());
797                 pr.setToOpenTab(true);
798                 //loaded.add(pr);
799                 return pr;
800             } else {
801                 // * means "guess the format":
802                 System.out.println(Globals.lang("Importing in unknown format")
803                     + ": " + data[0]);
804
805                 Object[] o =
806                     Globals.importFormatReader.importUnknownFormat(data[0]
807                         .replaceAll("~", System.getProperty("user.home")));
808                 String formatName = (String) o[0];
809
810                 if (formatName.equals(ImportFormatReader.BIBTEX_FORMAT)) {
811                     ParserResult pr = (ParserResult)o[1];
812                     pr.setToOpenTab(true);
813                     //loaded.add(pr);
814                     return pr;
815                 }
816                 else {
817                     List entries = (java.util.List) o[1];
818                     if (entries != null)
819                         System.out.println(Globals.lang("Format used") + ": "
820                             + formatName);
821                     else
822                         System.out.println(Globals.lang(
823                                 "Could not find a suitable import format."));
824
825                     if (entries != null) {
826                         BibtexDatabase base = ImportFormatReader.createDatabase(entries);
827                         ParserResult pr = new ParserResult(base, null, new HashMap());
828
829                         //pr.setFile(new File(data[0]));
830                         pr.setToOpenTab(true);
831                         //loaded.add(pr);
832                         return pr;
833                     }
834                 }
835
836             }
837         } catch (IOException ex) {
838             System.err.println(Globals.lang("Error opening file") + " '"
839                 + data[0] + "': " + ex.getMessage());
840         }
841
842         return null;
843     }
844 }