package net.sf.jabref.imports; import java.io.File; import java.util.ArrayList; import java.util.Enumeration; import java.util.Iterator; import java.util.List; import javax.swing.JOptionPane; import net.sf.jabref.BaseAction; import net.sf.jabref.BasePanel; import net.sf.jabref.BibtexDatabase; import net.sf.jabref.BibtexEntry; import net.sf.jabref.BibtexString; import net.sf.jabref.Globals; import net.sf.jabref.JabRefFrame; import net.sf.jabref.KeyCollisionException; import net.sf.jabref.MergeDialog; import net.sf.jabref.MetaData; import net.sf.jabref.Util; import net.sf.jabref.gui.FileDialogs; import net.sf.jabref.groups.AbstractGroup; import net.sf.jabref.groups.AllEntriesGroup; import net.sf.jabref.groups.ExplicitGroup; import net.sf.jabref.groups.GroupTreeNode; import net.sf.jabref.undo.NamedCompound; import net.sf.jabref.undo.UndoableInsertEntry; import net.sf.jabref.undo.UndoableInsertString; /** * Created by IntelliJ IDEA. * User: alver * Date: May 18, 2006 * Time: 9:49:02 PM * To change this template use File | Settings | File Templates. */ public class AppendDatabaseAction extends BaseAction { private JabRefFrame frame; private BasePanel panel; private List<File> filesToOpen = new ArrayList<File>(); public AppendDatabaseAction(JabRefFrame frame, BasePanel panel) { this.frame = frame; this.panel = panel; } public void action() { filesToOpen.clear(); final MergeDialog md = new MergeDialog(frame, Globals.lang("Append database"), true); Util.placeDialog(md, panel); md.setVisible(true); if (md.isOkPressed()) { String[] chosen = FileDialogs.getMultipleFiles(frame.getFrame(), new File(Globals.prefs.get("workingDirectory")), null, false); //String chosenFile = Globals.getNewFile(frame, new File(Globals.prefs.get("workingDirectory")), // null, JFileChooser.OPEN_DIALOG, false); if(chosen == null) return; for (int i=0; i<chosen.length; i++) filesToOpen.add(new File(chosen[i])); // Run the actual open in a thread to prevent the program // locking until the file is loaded. (new Thread() { public void run() { openIt(md.importEntries(), md.importStrings(), md.importGroups(), md.importSelectorWords()); } }).start(); //frame.getFileHistory().newFile(panel.fileToOpen.getPath()); } } void openIt(boolean importEntries, boolean importStrings, boolean importGroups, boolean importSelectorWords) { if (filesToOpen.size() == 0) return; for (Iterator<File> i = filesToOpen.iterator(); i.hasNext();) { File file = i.next(); try { Globals.prefs.put("workingDirectory", file.getPath()); // Should this be done _after_ we know it was successfully opened? String encoding = Globals.prefs.get("defaultEncoding"); ParserResult pr = OpenDatabaseAction.loadDatabase(file, encoding); mergeFromBibtex(frame, panel, pr, importEntries, importStrings, importGroups, importSelectorWords); panel.output(Globals.lang("Imported from database") + " '" + file.getPath() + "'"); } catch (Throwable ex) { ex.printStackTrace(); JOptionPane.showMessageDialog (panel, ex.getMessage(), "Open database", JOptionPane.ERROR_MESSAGE); } } } public static void mergeFromBibtex(JabRefFrame frame, BasePanel panel, ParserResult pr, boolean importEntries, boolean importStrings, boolean importGroups, boolean importSelectorWords) throws KeyCollisionException { BibtexDatabase fromDatabase = pr.getDatabase(); ArrayList<BibtexEntry> appendedEntries = new ArrayList<BibtexEntry>(); ArrayList<BibtexEntry> originalEntries = new ArrayList<BibtexEntry>(); BibtexDatabase database = panel.database(); BibtexEntry originalEntry; NamedCompound ce = new NamedCompound(Globals.lang("Append database")); MetaData meta = new MetaData(pr.getMetaData(), pr.getDatabase()); if (importEntries) { // Add entries boolean overwriteOwner = Globals.prefs.getBoolean("overwriteOwner"); boolean overwriteTimeStamp = Globals.prefs.getBoolean("overwriteTimeStamp"); for (String key : fromDatabase.getKeySet()){ originalEntry = fromDatabase.getEntryById(key); BibtexEntry be = (BibtexEntry) (originalEntry.clone()); be.setId(Util.createNeutralId()); Util.setAutomaticFields(be, overwriteOwner, overwriteTimeStamp); database.insertEntry(be); appendedEntries.add(be); originalEntries.add(originalEntry); ce.addEdit(new UndoableInsertEntry(database, be, panel)); } } if (importStrings) { for (BibtexString bs : fromDatabase.getStringValues()){ if (!database.hasStringLabel(bs.getName())) { database.addString(bs); ce.addEdit(new UndoableInsertString(panel, database, bs)); } } } if (importGroups) { GroupTreeNode newGroups = meta.getGroups(); if (newGroups != null) { // ensure that there is always only one AllEntriesGroup if (newGroups.getGroup() instanceof AllEntriesGroup) { // create a dummy group ExplicitGroup group = new ExplicitGroup("Imported", AbstractGroup.INDEPENDENT); // JZTODO lyrics newGroups.setGroup(group); for (int i = 0; i < appendedEntries.size(); ++i) group.addEntry(appendedEntries.get(i)); } // groupsSelector is always created, even when no groups // have been defined. therefore, no check for null is // required here frame.groupSelector.addGroups(newGroups, ce); // for explicit groups, the entries copied to the mother fromDatabase have to // be "reassigned", i.e. the old reference is removed and the reference // to the new fromDatabase is added. GroupTreeNode node; ExplicitGroup group; BibtexEntry entry; for (Enumeration<GroupTreeNode> e = newGroups .preorderEnumeration(); e.hasMoreElements();) { node = e.nextElement(); if (!(node.getGroup() instanceof ExplicitGroup)) continue; group = (ExplicitGroup) node.getGroup(); for (int i = 0; i < originalEntries.size(); ++i) { entry = originalEntries.get(i); if (group.contains(entry)) { group.removeEntry(entry); group.addEntry(appendedEntries.get(i)); } } } frame.groupSelector.revalidateGroups(); } } if (importSelectorWords) { for (String s : meta){ if (s.startsWith(Globals.SELECTOR_META_PREFIX)) { panel.metaData().putData(s, meta.getData(s)); } } } ce.end(); panel.undoManager.addEdit(ce); panel.markBaseChanged(); } }