256b63e9ff442937dea824b53fcbfcc6015343b7
[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 com.jgoodies.looks.FontPolicies;
28 import com.jgoodies.looks.FontPolicy;
29 import com.jgoodies.looks.FontSet;
30 import com.jgoodies.looks.FontSets;
31 import com.jgoodies.looks.plastic.Plastic3DLookAndFeel;
32 import com.jgoodies.looks.windows.WindowsLookAndFeel;
33 import gnu.dtools.ritopt.BooleanOption;
34 import gnu.dtools.ritopt.Options;
35 import gnu.dtools.ritopt.StringOption;
36 import net.sf.jabref.export.*;
37 import net.sf.jabref.imports.EntryFetcher;
38 import net.sf.jabref.imports.ImportInspectionCommandLine;
39 import net.sf.jabref.imports.OpenDatabaseAction;
40 import net.sf.jabref.imports.ParserResult;
41 import net.sf.jabref.plugin.PluginCore;
42 import net.sf.jabref.plugin.SidePanePlugin;
43 import net.sf.jabref.plugin.core.JabRefPlugin;
44 import net.sf.jabref.plugin.core.generated._JabRefPlugin;
45 import net.sf.jabref.plugin.core.generated._JabRefPlugin.EntryFetcherExtension;
46 import net.sf.jabref.remote.RemoteListener;
47 import net.sf.jabref.util.Pair;
48 import net.sf.jabref.wizard.auximport.AuxCommandLine;
49
50 import javax.swing.*;
51 import javax.swing.plaf.metal.MetalLookAndFeel;
52 import java.awt.*;
53 import java.awt.event.KeyEvent;
54 import java.io.File;
55 import java.io.FileNotFoundException;
56 import java.io.IOException;
57 import java.util.Collection;
58 import java.util.List;
59 import java.util.Vector;
60
61 /**
62  * JabRef Main Class - The application gets started here.
63  *
64  */
65 public class JabRef {
66     
67         public static JabRef singleton;
68     public static RemoteListener remoteListener = null;
69     public JabRefFrame jrf;
70     public Options options;
71     public Frame splashScreen = null;
72
73     boolean graphicFailure = false;
74
75     StringOption importFile, exportFile, exportPrefs, importPrefs, auxImExport, importToOpenBase, fetcherEngine;
76     BooleanOption helpO, disableGui, blank, loadSess, showVersion, disableSplash;
77     
78     public static void main(String[] args) {
79         new JabRef(args);
80     }
81
82     protected JabRef(String[] args) {
83
84                 singleton = this;
85
86                 // The following two lines signal that the system proxy settings should
87                 // be used:
88                 System.setProperty("java.net.useSystemProxies", "true");
89                 System.getProperties().put("proxySet", "true");
90
91                 JabRefPreferences prefs = JabRefPreferences.getInstance();
92         Globals.startBackgroundTasks();
93                 Globals.prefs = prefs;
94                 Globals.setLanguage(prefs.get("language"), "");
95
96                 /*
97                  * The Plug-in System is started automatically on the first call to
98                  * PluginCore.getManager().
99                  * 
100                  * Plug-ins are activated on the first call to their getInstance method.
101                  */
102
103         // Update which fields should be treated as numeric, based on preferences:
104         BibtexFields.setNumericFieldsFromPrefs();
105                 
106                 /* Build list of Import and Export formats */
107                 Globals.importFormatReader.resetImportFormats();
108                 BibtexEntryType.loadCustomEntryTypes(prefs);
109                 ExportFormats.initAllExports();
110                 
111                 // Read list(s) of journal names and abbreviations:
112         Globals.initializeJournalNames();
113
114                 // Check for running JabRef
115                 if (Globals.prefs.getBoolean("useRemoteServer")) {
116                         remoteListener = RemoteListener.openRemoteListener(this);
117
118                         if (remoteListener == null) {
119                                 // Unless we are alone, try to contact already running JabRef:
120                                 if (RemoteListener.sendToActiveJabRefInstance(args)) {
121
122                                         /*
123                                          * We have successfully sent our command line options
124                                          * through the socket to another JabRef instance. So we
125                                          * assume it's all taken care of, and quit.
126                                          */
127                                         System.out
128                                                         .println(Globals
129                                                                         .lang("Arguments passed on to running JabRef instance. Shutting down."));
130                                         System.exit(0);
131                                 }
132                         } else {
133                                 // No listener found, thus we are the first instance to be
134                                 // started.
135                                 remoteListener.start();
136                         }
137                 }
138
139                 /*
140                  * See if the user has a personal journal list set up. If so, add these
141                  * journal names and abbreviations to the list:
142                  */
143                 String personalJournalList = prefs.get("personalJournalList");
144                 if (personalJournalList != null) {
145                         try {
146                                 Globals.journalAbbrev.readJournalList(new File(
147                                                 personalJournalList));
148                         } catch (FileNotFoundException e) {
149                                 e.printStackTrace();
150                         }
151                 }
152
153                 /*
154                  * Make sure of a proper cleanup when quitting (e.g. deleting temporary
155                  * files).
156                  * 
157                  * CO 2007-07-12: Since this is deprecated, commented out:
158                  * 
159                  * System.runFinalizersOnExit(true);
160                  * 
161                  */
162                 
163                 openWindow(processArguments(args, true));
164         }
165
166     private void setupOptions() {
167
168         importFile = new StringOption("");
169         exportFile = new StringOption("");
170         helpO = new BooleanOption();
171         disableGui = new BooleanOption();
172         disableSplash = new BooleanOption();
173         blank = new BooleanOption();
174         loadSess = new BooleanOption();
175         showVersion = new BooleanOption();
176         exportPrefs = new StringOption("jabref_prefs.xml");
177         importPrefs = new StringOption("jabref_prefs.xml");
178         auxImExport = new StringOption("");
179         importToOpenBase = new StringOption("");
180         fetcherEngine = new StringOption("");
181
182         options = new Options("JabRef "); // Create an options repository.
183         options.setVersion(GUIGlobals.version);
184
185         importFile.setDescription("imopoepuoeu"); //Globals.lang);
186         options.register("version", 'v',
187                 Globals.lang("Display version"), showVersion);
188         options.register("nogui", 'n',
189             Globals.lang("No GUI. Only process command line options."), disableGui);
190         options.register("nosplash", 's',
191                 Globals.lang("Do not show splash window at startup"), disableSplash);
192         options.register("import", 'i',
193             Globals.lang("Import file") + ": " + Globals.lang("filename")
194             + "[,import format]", importFile);
195         options.register("output", 'o',
196             Globals.lang("Output or export file") + ": " + Globals.lang("filename")
197             + "[,export format]", exportFile);
198         options.register("help", 'h',
199             Globals.lang("Display help on command line options"), helpO);
200         options.register("loads", 'l', Globals.lang("Load session"), loadSess);
201         options.register("prexp", 'x', Globals.lang("Export preferences to file"),
202             exportPrefs);
203         options.register("primp", 'p', Globals.lang("Import preferences from file"),
204             importPrefs);
205         options.register("aux", 'a',
206             Globals.lang("Subdatabase from aux") + ": " + Globals.lang("file")+"[.aux]" + ","+Globals.lang("new")+"[.bib]",
207             auxImExport);
208         options.register("blank", 'b', Globals.lang("Do not open any files at startup"), blank);
209
210         options.register("importToOpen", '\0', Globals.lang("Import to open tab"), importToOpenBase);
211
212         options.register("fetch", 'f', Globals.lang("Run Fetcher, e.g. \"--fetch=Medline:cancer\""), fetcherEngine);
213
214         options.setUseMenu(false);
215     }
216
217     public Vector<ParserResult> processArguments(String[] args, boolean initialStartup) {
218
219         setupOptions();
220         String[] leftOver = options.process(args);
221
222         if (initialStartup && showVersion.isInvoked()) {
223             options.displayVersion();
224             disableGui.setInvoked(true);
225         }
226
227         if (initialStartup && helpO.isInvoked()) {
228             System.out.println("jabref [options] [bibtex-file]\n");
229             System.out.println(options.getHelp());
230
231             String importFormats = Globals.importFormatReader.getImportFormatList();
232             System.out.println(Globals.lang("Available import formats") + ":\n"
233                 + importFormats);
234
235             String outFormats = ExportFormats.getConsoleExportList(70, 20, "\t");
236             System.out.println(Globals.lang("Available export formats") + ": " + outFormats
237                 + ".");
238             System.exit(0);
239         }
240         
241         boolean commandmode = disableGui.isInvoked() || fetcherEngine.isInvoked();
242         
243         // First we quickly scan the command line parameters for any that signal
244         // that the GUI
245         // should not be opened. This is used to decide whether we should show the
246         // splash screen or not.
247         if (initialStartup && !commandmode && !disableSplash.isInvoked()) {
248             try {
249                 splashScreen = SplashScreen.splash();
250             } catch (Throwable ex) {
251                 graphicFailure = true;
252                 System.err.println(Globals.lang("Unable to create graphical interface")
253                     + ".");
254             }
255         }
256
257         // Vector to put imported/loaded database(s) in.
258         Vector<ParserResult> loaded = new Vector<ParserResult>();
259         Vector<String> toImport = new Vector<String>();
260         if (!blank.isInvoked() && (leftOver.length > 0))  {
261             for (int i = 0; i < leftOver.length; i++) {
262                 // Leftover arguments that have a "bib" extension are interpreted as
263                 // bib files to open. Other files, and files that could not be opened
264                 // as bib, we try to import instead.
265                 boolean bibExtension = leftOver[i].toLowerCase().endsWith("bib");
266                 ParserResult pr = null;
267                 if (bibExtension)
268                     pr = openBibFile(leftOver[i]);
269
270                 if ((pr == null) || (pr == ParserResult.INVALID_FORMAT)) {
271                     // We will try to import this file. Normally we
272                     // will import it into a new tab, but if this import has
273                     // been initiated by another instance through the remote
274                     // listener, we will instead import it into the current database.
275                     // This will enable easy integration with web browers that can
276                     // open a reference file in JabRef.
277                     if (initialStartup) {
278                         toImport.add(leftOver[i]);
279                     } else {
280                         ParserResult res = importToOpenBase(leftOver[i]);
281                         if (res != null)
282                             loaded.add(res);
283                     }
284                 }
285                 else
286                     loaded.add(pr);
287
288             }
289         }
290
291         if (!blank.isInvoked() && importFile.isInvoked()) {
292             toImport.add(importFile.getStringValue());
293         }
294
295         for (String filenameString : toImport) {
296                         ParserResult pr = importFile(filenameString);
297                         if (pr != null)
298                                 loaded.add(pr);
299                 }
300
301         if (!blank.isInvoked() && importToOpenBase.isInvoked()) {
302             ParserResult res = importToOpenBase(importToOpenBase.getStringValue());
303             if (res != null)
304                 loaded.add(res);
305         }
306
307         if (!blank.isInvoked() && fetcherEngine.isInvoked()) {
308             ParserResult res = fetch(fetcherEngine.getStringValue());
309             if (res != null)
310                 loaded.add(res);
311         }
312
313         if (exportFile.isInvoked()) {
314             if (loaded.size() > 0) {
315                 String[] data = exportFile.getStringValue().split(",");
316
317                 if (data.length == 1) {
318                     // This signals that the latest import should be stored in BibTeX
319                     // format to the given file.
320                     if (loaded.size() > 0) {
321                         ParserResult pr =
322                             loaded.elementAt(loaded.size() - 1);
323
324                         try {
325                             System.out.println(Globals.lang("Saving") + ": " + data[0]);
326                             SaveSession session = FileActions.saveDatabase(pr.getDatabase(),
327                                 new MetaData(pr.getMetaData(),pr.getDatabase()), new File(data[0]), Globals.prefs,
328                                 false, false, Globals.prefs.get("defaultEncoding"));
329                             // Show just a warning message if encoding didn't work for all characters:
330                             if (!session.getWriter().couldEncodeAll())
331                                 System.err.println(Globals.lang("Warning")+": "+
332                                     Globals.lang("The chosen encoding '%0' could not encode the following characters: ",
333                                     session.getEncoding())+session.getWriter().getProblemCharacters());
334                             session.commit();
335                         } catch (SaveException ex) {
336                             System.err.println(Globals.lang("Could not save file") + " '"
337                                 + data[0] + "': " + ex.getMessage());
338                         }
339                     } else
340                         System.err.println(Globals.lang(
341                                 "The output option depends on a valid import option."));
342                 } else if (data.length == 2) {
343                     // This signals that the latest import should be stored in the given
344                     // format to the given file.
345                     ParserResult pr = loaded.elementAt(loaded.size() - 1);
346
347                     // Set the global variable for this database's file directory before exporting,
348                     // so formatters can resolve linked files correctly.
349                     // (This is an ugly hack!)
350                     MetaData metaData = new MetaData(pr.getMetaData(), pr.getDatabase());
351                     metaData.setFile(pr.getFile());
352                     Globals.prefs.fileDirForDatabase = metaData.getFileDirectory(GUIGlobals.FILE_FIELD);
353                     System.out.println(Globals.lang("Exporting") + ": " + data[0]);
354                     IExportFormat format = ExportFormats.getExportFormat(data[1]);
355                     if (format != null) {
356                         // We have an ExportFormat instance:
357                         try {
358                             format.performExport(pr.getDatabase(), 
359                                     new MetaData(pr.getMetaData(), pr.getDatabase()),
360                                     data[0], pr.getEncoding(), null);
361                         } catch (Exception ex) {
362                             System.err.println(Globals.lang("Could not export file")
363                                 + " '" + data[0] + "': " + ex.getMessage());
364                         }
365                     }
366                     else
367                         System.err.println(Globals.lang("Unknown export format")
368                                 + ": " + data[1]);
369
370                 }
371             } else
372                 System.err.println(Globals.lang(
373                         "The output option depends on a valid import option."));
374         }
375
376         //Util.pr(": Finished export");
377
378         if (exportPrefs.isInvoked()) {
379             try {
380                 Globals.prefs.exportPreferences(exportPrefs.getStringValue());
381             } catch (IOException ex) {
382                 Util.pr(ex.getMessage());
383             }
384         }
385
386
387         if (importPrefs.isInvoked()) {
388             try {
389                 Globals.prefs.importPreferences(importPrefs.getStringValue());
390                 BibtexEntryType.loadCustomEntryTypes(Globals.prefs);
391             }
392             catch (IOException ex) {
393                 Util.pr(ex.getMessage());
394             }
395         }
396
397         if (!blank.isInvoked() && auxImExport.isInvoked()) {
398             boolean usageMsg = false;
399
400             if (loaded.size() > 0) // bibtex file loaded
401              {
402                 String[] data = auxImExport.getStringValue().split(",");
403
404                 if (data.length == 2) {
405                     ParserResult pr = loaded.firstElement();
406                     AuxCommandLine acl = new AuxCommandLine(data[0], pr.getDatabase());
407                     BibtexDatabase newBase = acl.perform();
408
409                     boolean notSavedMsg = false;
410
411                     // write an output, if something could be resolved
412                     if (newBase != null) {
413                         if (newBase.getEntryCount() > 0) {
414                             String subName = Util.getCorrectFileName(data[1], "bib");
415
416                             try {
417                                 System.out.println(Globals.lang("Saving") + ": "
418                                     + subName);
419                                 SaveSession session = FileActions.saveDatabase(newBase, new MetaData(), // no Metadata
420                                     new File(subName), Globals.prefs, false, false,
421                                     Globals.prefs.get("defaultEncoding"));
422                                 // Show just a warning message if encoding didn't work for all characters:
423                                 if (!session.getWriter().couldEncodeAll())
424                                     System.err.println(Globals.lang("Warning")+": "+
425                                         Globals.lang("The chosen encoding '%0' could not encode the following characters: ",
426                                         session.getEncoding())+session.getWriter().getProblemCharacters());
427                                 session.commit();
428                             } catch (SaveException ex) {
429                                 System.err.println(Globals.lang("Could not save file")
430                                     + " '" + subName + "': " + ex.getMessage());
431                             }
432
433                             notSavedMsg = true;
434                         }
435                     }
436
437                     if (!notSavedMsg)
438                         System.out.println(Globals.lang("no database generated"));
439                 } else
440                     usageMsg = true;
441             } else
442                 usageMsg = true;
443
444             if (usageMsg) {
445                 System.out.println(Globals.lang("no base-bibtex-file specified"));
446                 System.out.println(Globals.lang("usage") + " :");
447                 System.out.println(
448                     "jabref --aux infile[.aux],outfile[.bib] base-bibtex-file");
449             }
450         }
451
452         return loaded;
453     }
454
455     /**
456      * Run an entry fetcher from the command line.
457      * 
458      * Note that this only works headlessly if the EntryFetcher does not show
459      * any GUI.
460      * 
461      * @param fetchCommand
462      *            A string containing both the fetcher to use (id of
463      *            EntryFetcherExtension minus Fetcher) and the search query,
464      *            separated by a :
465      * @return A parser result containing the entries fetched or null if an
466      *         error occurred.
467      */
468     protected ParserResult fetch(String fetchCommand) {
469
470         if (fetchCommand == null || !fetchCommand.contains(":") ||
471             fetchCommand.split(":").length != 2) {
472             System.out.println(Globals.lang("Expected syntax for --fetch='<name of fetcher>:<query>'"));
473             System.out.println(Globals.lang("The following fetchers are available:"));
474             for (EntryFetcherExtension e : JabRefPlugin.getInstance(PluginCore.getManager())
475                 .getEntryFetcherExtensions()) {
476                 System.out.println("  " + e.getId().replaceAll("Fetcher", "").toLowerCase());
477             }
478             return null;
479         }
480
481         String engine = fetchCommand.split(":")[0];
482         String query = fetchCommand.split(":")[1];
483
484         EntryFetcher fetcher = null;
485         for (EntryFetcherExtension e : JabRefPlugin.getInstance(PluginCore.getManager())
486             .getEntryFetcherExtensions()) {
487             if (engine.toLowerCase().equals(e.getId().replaceAll("Fetcher", "").toLowerCase()))
488                 fetcher = e.getEntryFetcher();
489         }
490
491         if (fetcher == null) {
492             System.out.println(Globals.lang("Could not find fetcher '%0'", engine));
493             System.out.println(Globals.lang("The following fetchers are available:"));
494             for (EntryFetcherExtension e : JabRefPlugin.getInstance(PluginCore.getManager())
495                 .getEntryFetcherExtensions()) {
496                 System.out.println("  " + e.getId().replaceAll("Fetcher", "").toLowerCase());
497             }
498             return null;
499         }
500
501         System.out.println(Globals.lang("Running Query '%0' with fetcher '%1'.", query, engine) +
502             " " + Globals.lang("Please wait!"));
503         Collection<BibtexEntry> result = new ImportInspectionCommandLine().query(query, fetcher);
504
505         if (result == null || result.size() == 0) {
506             System.out.println(Globals.lang(
507                 "Query '%0' with fetcher '%1' did not return any results.", query, engine));
508             return null;
509         }
510
511         return new ParserResult(result);
512     }
513
514         public void openWindow(Vector<ParserResult> loaded) {
515         if (!graphicFailure && !disableGui.isInvoked()) {
516             // Call the method performCompatibilityUpdate(), which does any
517             // necessary changes for users with a preference set from an older
518             // Jabref version.
519             Util.performCompatibilityUpdate();
520
521
522             // Set up custom or default icon theme:
523             GUIGlobals.setUpIconTheme();
524
525             // TODO: remove temporary registering of external file types?
526             Globals.prefs.updateExternalFileTypes();
527
528            // This property is set to make the Mac OSX Java VM move the menu bar to
529             // the top
530             // of the screen, where Mac users expect it to be.
531             System.setProperty("apple.laf.useScreenMenuBar", "true");
532
533             // Set antialiasing on everywhere. This only works in JRE >= 1.5.
534             // Or... it doesn't work, period.
535             //System.setProperty("swing.aatext", "true");
536             // If we are not on Mac, deal with font sizes and LookAndFeels:
537             if (!Globals.ON_MAC) {
538                 int fontSizes = Globals.prefs.getInt("menuFontSize");
539                 boolean overrideDefaultFonts = Globals.prefs.getBoolean("overrideDefaultFonts");
540                 String defaultLookAndFeel;
541
542                 if (Globals.ON_WIN)
543                     defaultLookAndFeel = GUIGlobals.windowsDefaultLookAndFeel;
544                 else
545                     defaultLookAndFeel = GUIGlobals.linuxDefaultLookAndFeel;
546
547                 String lookAndFeel = null;
548
549                 if (!Globals.prefs.getBoolean("useDefaultLookAndFeel"))
550                     lookAndFeel = Globals.prefs.get("lookAndFeel");
551                 else
552                     lookAndFeel = defaultLookAndFeel;
553
554                 LookAndFeel lnf = null;
555                 Object objLnf = null;
556
557
558                 try {
559                     if (lookAndFeel != null)
560                         objLnf = Class.forName(lookAndFeel).newInstance();
561                     else
562                         objLnf = Class.forName(defaultLookAndFeel).newInstance();
563                 } catch (Exception ex) {
564                     ex.printStackTrace();
565
566                     try {
567                         objLnf = Class.forName(defaultLookAndFeel).newInstance();
568                     } catch (Exception ex2) {
569                     }
570                 }
571
572                 if (objLnf != null)
573                     lnf = (LookAndFeel) objLnf;
574
575                 // Set font sizes if we are using a JGoodies look and feel.
576                 if ((lnf != null) && (lnf instanceof Plastic3DLookAndFeel)) {
577
578                     //UIManager.put("jgoodies.popupDropShadowEnabled", Boolean.TRUE);
579                     MetalLookAndFeel.setCurrentTheme(new
580                      com.jgoodies.looks.plastic.theme.SkyBluer());
581
582                     // Set a "model" icon size, so menu items are evenly spaced even though
583                     // only some items have icons. We load an arbitrary icon and look at
584                     // its size to determine what size to use:
585                     int defaultIconSize = GUIGlobals.getImage("open").getIconWidth();
586                     com.jgoodies.looks.Options.setDefaultIconSize
587                             (new Dimension(defaultIconSize, defaultIconSize));
588
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                         Plastic3DLookAndFeel.setFontPolicy(fixedPolicy);
598                     }
599
600                     //Plastic3DLookAndFeel plLnf = (Plastic3DLookAndFeel) lnf;
601                 }
602                 else if ((lnf != null) && (lnf instanceof WindowsLookAndFeel)) {
603
604                     // Set a "model" icon size, so menu items are evenly spaced even though
605                     // only some items have icons. We load an arbitrary icon and look at
606                     // its size to determine what size to use:
607                     int defaultIconSize = GUIGlobals.getImage("open").getIconWidth();
608                     com.jgoodies.looks.Options.setDefaultIconSize
609                         (new Dimension(defaultIconSize, defaultIconSize));
610
611                     if (overrideDefaultFonts) {
612                         FontSet fontSet = FontSets.createDefaultFontSet(
613                             new Font("Tahoma", Font.PLAIN, fontSizes),    // control font
614                             new Font("Tahoma", Font.PLAIN, fontSizes),    // menu font
615                             new Font("Tahoma", Font.BOLD, fontSizes)     // title font
616                             );
617                         FontPolicy fixedPolicy = FontPolicies.createFixedPolicy(fontSet);
618                         WindowsLookAndFeel.setFontPolicy(fixedPolicy);
619                     }
620
621                     //WindowsLookAndFeel plLnf = (WindowsLookAndFeel) lnf;
622                 }
623
624                 if (lnf != null) {
625                     try {
626
627                         UIManager.setLookAndFeel(lnf);
628
629                         if (!Globals.ON_WIN) {
630                             UIManager.put("SimpleInternalFrame.activeTitleBackground", GUIGlobals.gradientBlue);
631                         }
632
633                         if (!Globals.ON_WIN && !Globals.ON_MAC) {
634                             // For Linux, add Enter as button click key:
635                             UIDefaults def = UIManager.getDefaults();
636                             InputMap im = (InputMap)def.get("Button.focusInputMap");
637                             im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, false), "pressed");
638                             im.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, 0, true), "released");
639                         }
640                     } catch (Throwable ex) {
641                         ex.printStackTrace();
642                         System.err.println("Trying to set system default Look&Feel...");
643
644                         // if desired lnf could not be set, try system default
645                         try {
646                             UIManager.setLookAndFeel(UIManager
647                                 .getSystemLookAndFeelClassName());
648                         } catch (Throwable e) {
649                             e.printStackTrace();
650                         }
651                     }
652
653                     //LookAndFeel lnf = new com.sun.java.swing.plaf.gtk.GTKLookAndFeel();
654                     //Look1AndFeel lnf = new
655                     // com.incors.plaf.kunststoff.KunststoffLookAndFeel();
656                     //com.incors.plaf.kunststoff.KunststoffLookAndFeel.setCurrentTheme(new
657                     // com.incors.plaf.kunststoff.themes.KunststoffDesktopTheme());
658                 }
659
660             }
661
662
663             // If the option is enabled, open the last edited databases, if any.
664             if (!blank.isInvoked() && Globals.prefs.getBoolean("openLastEdited") && (Globals.prefs.get("lastEdited") != null)) {
665                 // How to handle errors in the databases to open?
666                 String[] names = Globals.prefs.getStringArray("lastEdited");
667 lastEdLoop: 
668                 for (int i = 0; i < names.length; i++) {
669                     File fileToOpen = new File(names[i]);
670
671                     for (int j = 0; j < loaded.size(); j++) {
672                         ParserResult pr = loaded.elementAt(j);
673
674                         if ((pr.getFile() != null) &&pr.getFile().equals(fileToOpen))
675                             continue lastEdLoop;
676                     }
677
678                     if (fileToOpen.exists()) {
679                         ParserResult pr = openBibFile(names[i]);
680
681                         if (pr != null) {
682
683                             if (pr == ParserResult.INVALID_FORMAT) {
684                                 System.out.println(Globals.lang("Error opening file")+" '"+fileToOpen.getPath()+"'");
685                             }
686                             else
687                                 loaded.add(pr);
688
689                         }
690                     }
691                 }
692             }
693
694             GUIGlobals.init();
695             GUIGlobals.CURRENTFONT =
696                 new Font(Globals.prefs.get("fontFamily"), Globals.prefs.getInt("fontStyle"),
697                     Globals.prefs.getInt("fontSize"));
698
699             //Util.pr(": Initializing frame");
700             jrf = new JabRefFrame();
701
702             // Add all loaded databases to the frame:
703             boolean first = true;
704             if (loaded.size() > 0) {
705                 for (ParserResult pr : loaded){
706                             jrf.addTab(pr.getDatabase(), pr.getFile(),
707                             pr.getMetaData(), pr.getEncoding(), first);
708                     first = false;
709                 }
710             }
711
712             if (loadSess.isInvoked())
713                 jrf.loadSessionAction.actionPerformed(new java.awt.event.ActionEvent(
714                         jrf, 0, ""));
715
716             if (splashScreen != null) {// do this only if splashscreen was actually created
717                 splashScreen.dispose();
718                 splashScreen = null;
719             }
720
721             /*JOptionPane.showMessageDialog(null, Globals.lang("Please note that this "
722                 +"is an early beta version. Do not use it without backing up your files!"),
723                     Globals.lang("Beta version"), JOptionPane.WARNING_MESSAGE);*/
724
725             //Util.pr(": Showing frame");
726             jrf.setVisible(true);
727             // If we are set to remember the window location, we also remember the maximised
728             // state. This needs to be set after the window has been made visible, so we
729             // do it here:
730              if (Globals.prefs.getBoolean("rememberWindowLocation") &&
731                      Globals.prefs.getBoolean("windowMaximised")) {
732                  jrf.setExtendedState(JFrame.MAXIMIZED_BOTH);
733              }
734
735
736             // TEST TEST TEST TEST TEST TEST
737             startSidePanePlugins(jrf);
738
739             for (int i = 0; i < loaded.size(); i++) {
740                 ParserResult pr = loaded.elementAt(i);
741                 if (Globals.prefs.getBoolean("displayKeyWarningDialogAtStartup") && pr.hasWarnings()) {
742                     String[] wrns = pr.warnings();
743                     StringBuffer wrn = new StringBuffer();
744                     for (int j = 0; j<wrns.length; j++)
745                         wrn.append(j + 1).append(". ").append(wrns[j]).append("\n");
746                     if (wrn.length() > 0)
747                         wrn.deleteCharAt(wrn.length() - 1);
748                     jrf.showBaseAt(i);
749                     JOptionPane.showMessageDialog(jrf, wrn.toString(),
750                         Globals.lang("Warnings"),
751                         JOptionPane.WARNING_MESSAGE);
752                 }
753             }
754
755             // After adding the databases, go through each and see if
756             // any post open actions need to be done. For instance, checking
757             // if we found new entry types that can be imported, or checking
758             // if the database contents should be modified due to new features
759             // in this version of JabRef:
760             for (int i = 0; i < loaded.size(); i++) {
761                 ParserResult pr = loaded.elementAt(i);
762                 BasePanel panel = jrf.baseAt(i);
763                 OpenDatabaseAction.performPostOpenActions(panel, pr, true);
764             }
765
766             //Util.pr(": Finished adding panels");
767
768             if (loaded.size() > 0) {
769                 jrf.tabbedPane.setSelectedIndex(0);
770                 new FocusRequester(((BasePanel) jrf.tabbedPane.getComponentAt(0)).mainTable);
771             }
772         } else
773             System.exit(0);
774     }
775
776     /**
777      * Go through all registered instances of SidePanePlugin, and register them
778      * in the SidePaneManager.
779      *
780      * @param jrf The JabRefFrame.
781      */
782     private void startSidePanePlugins(JabRefFrame jrf) {
783
784         JabRefPlugin jabrefPlugin = JabRefPlugin.getInstance(PluginCore.getManager());
785         List<_JabRefPlugin.SidePanePluginExtension> plugins = jabrefPlugin.getSidePanePluginExtensions();
786         for (_JabRefPlugin.SidePanePluginExtension extension : plugins) {
787             SidePanePlugin plugin = extension.getSidePanePlugin();
788             plugin.init(jrf, jrf.sidePaneManager);
789             SidePaneComponent comp = plugin.getSidePaneComponent();
790             jrf.sidePaneManager.register(comp.getName(), comp);
791             jrf.addPluginMenuItem(plugin.getMenuItem());
792         }
793     }
794
795     public static ParserResult openBibFile(String name) {
796         System.out.println(Globals.lang("Opening") + ": " + name);
797
798         try {
799             File file = new File(name);
800             String encoding = Globals.prefs.get("defaultEncoding");
801             ParserResult pr = OpenDatabaseAction.loadDatabase(file, encoding);
802             if (pr == null)
803                 return ParserResult.INVALID_FORMAT;
804             pr.setFile(file);
805             if (pr.hasWarnings()) {
806                 String[] warn = pr.warnings();
807                 for (int i=0; i<warn.length; i++)
808                     System.out.println(Globals.lang("Warning")+": "+warn[i]);
809
810             }
811             return pr;
812         } catch (Throwable ex) {
813             //System.err.println(Globals.lang("Error opening file")+" '"+ name+"':
814             // "+ex.getMessage());
815             System.err.println(Globals.lang("Error opening file") + ": "
816                 + ex.getMessage());
817         }
818
819         return null;
820     }
821
822     public static ParserResult importFile(String argument){
823         String[] data = argument.split(",");
824         try {
825             if ((data.length > 1) && !"*".equals(data[1])) {
826                 System.out.println(Globals.lang("Importing") + ": " + data[0]);
827                 List<BibtexEntry> entries =
828                         Globals.importFormatReader.importFromFile(data[1],
829                                 data[0].replaceAll("~", System.getProperty("user.home")));
830                 return new ParserResult(entries);
831             } else {
832                 // * means "guess the format":
833                 System.out.println(Globals.lang("Importing in unknown format")
834                         + ": " + data[0]);
835                 
836                 Pair<String, ParserResult> importResult = 
837                     Globals.importFormatReader.importUnknownFormat(data[0]
838                             .replaceAll("~", System.getProperty("user.home")));
839                 
840                 if (importResult != null){
841                         System.out.println(Globals.lang("Format used") + ": "
842                         + importResult.p);
843                         
844                         return importResult.v;
845                 } else {
846                         System.out.println(Globals.lang(
847                                 "Could not find a suitable import format."));
848                 }
849             }
850         } catch (IOException ex) {
851             System.err.println(Globals.lang("Error opening file") + " '"
852                     + data[0] + "': " + ex.getLocalizedMessage());
853         }
854         return null;
855     }
856
857     /**
858      * Will open a file (like importFile), but will also request JabRef to focus on this database 
859      * @param argument See importFile.
860      * @return ParserResult with setToOpenTab(true)
861      */
862     public static ParserResult importToOpenBase(String argument) {
863         ParserResult result = importFile(argument);
864         
865         if (result != null)
866                 result.setToOpenTab(true);
867         
868         return result;
869     }
870 }