public void mouseClicked(MouseEvent e) { if (e.isPopupTrigger()) { processPopupTrigger(e); return; } // if (e.) final int col = entryTable.columnAtPoint(e.getPoint()), row = entryTable.rowAtPoint(e.getPoint()); if (col < PAD) { BibtexEntry entry = sortedEntries.get(row); BasePanel p = entryHome.get(entry); switch (col) { case FILE_COL: Object o = entry.getField(GUIGlobals.FILE_FIELD); if (o != null) { FileListTableModel tableModel = new FileListTableModel(); tableModel.setContent((String) o); if (tableModel.getRowCount() == 0) return; FileListEntry fl = tableModel.getEntry(0); (new ExternalFileMenuItem( frame, entry, "", fl.getLink(), null, p.metaData(), fl.getType())) .actionPerformed(null); } break; case URL_COL: Object link = entry.getField("url"); try { if (link != null) Util.openExternalViewer(p.metaData(), (String) link, "url"); } catch (IOException ex) { ex.printStackTrace(); } break; } } }
private void doMakePathsRelative(BibtexEntry entry, NamedCompound ce) { String oldValue = entry.getField(Globals.FILE_FIELD); if (oldValue == null) { return; } FileListTableModel flModel = new FileListTableModel(); flModel.setContent(oldValue); if (flModel.getRowCount() == 0) { return; } boolean changed = false; for (int i = 0; i < flModel.getRowCount(); i++) { FileListEntry flEntry = flModel.getEntry(i); String oldFileName = flEntry.getLink(); String newFileName = FileUtil.shortenFileName( new File(oldFileName), panel.metaData().getFileDirectory(Globals.FILE_FIELD)) .toString(); if (!oldFileName.equals(newFileName)) { flEntry.setLink(newFileName); changed = true; } } if (changed) { String newValue = flModel.getStringRepresentation(); assert (!oldValue.equals(newValue)); entry.setField(Globals.FILE_FIELD, newValue); ce.addEdit(new UndoableFieldChange(entry, Globals.FILE_FIELD, oldValue, newValue)); } }
/** * If the user has signalled the opening of a context menu, the event gets redirected to this * method. Here we open a file link menu if the user is pointing at a file link icon. Otherwise * a general context menu should be shown. * * @param e The triggering mouse event. */ public void processPopupTrigger(MouseEvent e) { BibtexEntry entry = sortedEntries.get(entryTable.rowAtPoint(e.getPoint())); BasePanel p = entryHome.get(entry); int col = entryTable.columnAtPoint(e.getPoint()); JPopupMenu menu = new JPopupMenu(); int count = 0; if (col == FILE_COL) { // We use a FileListTableModel to parse the field content: Object o = entry.getField(GUIGlobals.FILE_FIELD); FileListTableModel fileList = new FileListTableModel(); fileList.setContent((String) o); // If there are one or more links, open the first one: for (int i = 0; i < fileList.getRowCount(); i++) { FileListEntry flEntry = fileList.getEntry(i); String description = flEntry.getDescription(); if ((description == null) || (description.trim().length() == 0)) description = flEntry.getLink(); menu.add( new ExternalFileMenuItem( p.frame(), entry, description, flEntry.getLink(), flEntry.getType().getIcon(), p.metaData(), flEntry.getType())); count++; } } if (count > 0) menu.show(entryTable, e.getX(), e.getY()); }
public void listChanged(ListEvent<BibtexEntry> listEvent) { if (listEvent.getSourceList().size() == 1) { BibtexEntry entry = listEvent.getSourceList().get(0); // Find out which BasePanel the selected entry belongs to: BasePanel p = entryHome.get(entry); // Update the preview's metadata reference: preview.setMetaData(p.metaData()); // Update the preview's entry: preview.setEntry(entry); contentPane.setDividerLocation(0.5f); SwingUtilities.invokeLater( new Runnable() { public void run() { preview.scrollRectToVisible(toRect); } }); } }
private void doRenamePDFs(BibtexEntry entry, NamedCompound ce) { // Extract the path String oldValue = entry.getField(Globals.FILE_FIELD); if (oldValue == null) { return; } FileListTableModel flModel = new FileListTableModel(); flModel.setContent(oldValue); if (flModel.getRowCount() == 0) { return; } boolean changed = false; for (int i = 0; i < flModel.getRowCount(); i++) { String realOldFilename = flModel.getEntry(i).getLink(); if (cleanUpRenamePDFonlyRelativePaths.isSelected() && (new File(realOldFilename).isAbsolute())) { continue; } String newFilename = Util.getLinkedFileName(panel.database(), entry); // String oldFilename = bes.getField(GUIGlobals.FILE_FIELD); // would have to be stored for // undoing purposes // Add extension to newFilename newFilename = newFilename + "." + flModel.getEntry(i).getType().getExtension(); // get new Filename with path // Create new Path based on old Path and new filename File expandedOldFile = FileUtil.expandFilename( realOldFilename, panel.metaData().getFileDirectory(Globals.FILE_FIELD)); if (expandedOldFile.getParent() == null) { // something went wrong. Just skip this entry continue; } String newPath = expandedOldFile .getParent() .concat(System.getProperty("file.separator")) .concat(newFilename); if (new File(newPath).exists()) { // we do not overwrite files // TODO: we could check here if the newPath file is linked with the current entry. And if // not, we could add a link continue; } // do rename boolean renameSuccessful = FileUtil.renameFile(expandedOldFile.toString(), newPath); if (renameSuccessful) { changed = true; // Change the path for this entry String description = flModel.getEntry(i).getDescription(); ExternalFileType type = flModel.getEntry(i).getType(); flModel.removeEntry(i); // we cannot use "newPath" to generate a FileListEntry as newPath is absolute, but we want // to keep relative paths whenever possible File parent = (new File(realOldFilename)).getParentFile(); String newFileEntryFileName; if (parent == null) { newFileEntryFileName = newFilename; } else { newFileEntryFileName = parent.toString().concat(System.getProperty("file.separator")).concat(newFilename); } flModel.addEntry(i, new FileListEntry(description, newFileEntryFileName, type)); } else { unsuccessfulRenames++; } } if (changed) { String newValue = flModel.getStringRepresentation(); assert (!oldValue.equals(newValue)); entry.setField(Globals.FILE_FIELD, newValue); // we put an undo of the field content here // the file is not being renamed back, which leads to inconsistencies // if we put a null undo object here, the change by "doMakePathsRelative" would overwrite the // field value nevertheless. ce.addEdit(new UndoableFieldChange(entry, Globals.FILE_FIELD, oldValue, newValue)); } }
public void run() { if (!goOn) return; for (int i = 0; i < entries.length; i++) { BibtexEntry entry = entries[i]; // Make a list of all PDFs linked from this entry: List<File> files = new ArrayList<File>(); // First check the (legacy) "pdf" field: String pdf = entry.getField("pdf"); String dir = panel.metaData().getFileDirectory("pdf"); File f = Util.expandFilename(pdf, new String[] {dir, "."}); if (f != null) files.add(f); // Then check the "file" field: dir = panel.metaData().getFileDirectory(GUIGlobals.FILE_FIELD); String field = entry.getField(GUIGlobals.FILE_FIELD); if (field != null) { FileListTableModel tm = new FileListTableModel(); tm.setContent(field); for (int j = 0; j < tm.getRowCount(); j++) { FileListEntry flEntry = tm.getEntry(j); if ((flEntry.getType() != null) && (flEntry.getType().getName().toLowerCase().equals("pdf"))) { f = Util.expandFilename(flEntry.getLink(), new String[] {dir, "."}); if (f != null) files.add(f); } } } optDiag.progressArea.append(entry.getCiteKey() + "\n"); if (files.size() == 0) { skipped++; optDiag.progressArea.append(" " + Globals.lang("Skipped - No PDF linked") + ".\n"); } else for (File file : files) { if (!file.exists()) { skipped++; optDiag.progressArea.append( " " + Globals.lang("Skipped - PDF does not exist") + ":\n"); optDiag.progressArea.append(" " + file.getPath() + "\n"); } else { try { XMPUtil.writeXMP(file, entry, database); optDiag.progressArea.append(" " + Globals.lang("Ok") + ".\n"); entriesChanged++; } catch (Exception e) { optDiag.progressArea.append( " " + Globals.lang("Error while writing") + " '" + file.getPath() + "':\n"); optDiag.progressArea.append(" " + e.getLocalizedMessage() + "\n"); errors++; } } } if (optDiag.canceled) { optDiag.progressArea.append("\n" + Globals.lang("Operation canceled.\n")); break; } } optDiag.progressArea.append( "\n" + Globals.lang( "Finished writing XMP for %0 file (%1 skipped, %2 errors).", String.valueOf(entriesChanged), String.valueOf(skipped), String.valueOf(errors))); optDiag.done(); }
@Override public void run() { BasePanel panel = frame.basePanel(); if (panel == null) { return; } if (panel.getSelectedEntries().length == 0) { message = Localization.lang("No entries selected."); getCallBack().update(); return; } Map<String, IExportFormat> m = ExportFormats.getExportFormats(); IExportFormat[] formats = new ExportFormat[m.size()]; String[] array = new String[formats.length]; int piv = 0; for (IExportFormat format : m.values()) { formats[piv] = format; array[piv] = format.getDisplayName(); piv++; } JList list = new JList(array); list.setBorder(BorderFactory.createEtchedBorder()); list.setSelectionInterval(0, 0); list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); int answer = JOptionPane.showOptionDialog( frame, list, Localization.lang("Select format"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, new String[] {Localization.lang("Ok"), Localization.lang("Cancel")}, Localization.lang("Ok")); if (answer == JOptionPane.NO_OPTION) { return; } IExportFormat format = formats[list.getSelectedIndex()]; // Set the global variable for this database's file directory before exporting, // so formatters can resolve linked files correctly. // (This is an ugly hack!) Globals.prefs.fileDirForDatabase = frame.basePanel().metaData().getFileDirectory(GUIGlobals.FILE_FIELD); // Also store the database's file in a global variable: Globals.prefs.databaseFile = frame.basePanel().metaData().getFile(); /*final boolean custom = (list.getSelectedIndex() >= Globals.STANDARD_EXPORT_COUNT); String dir = null; if (custom) { int index = list.getSelectedIndex() - Globals.STANDARD_EXPORT_COUNT; dir = (String) (Globals.prefs.customExports.getElementAt(index)[1]); File f = new File(dir); lfName = f.getName(); lfName = lfName.substring(0, lfName.indexOf(".")); // Remove file name - we want the directory only. dir = f.getParent() + System.getProperty("file.separator"); } final String format = lfName, directory = dir; */ File tmp = null; Reader reader = null; try { // To simplify the exporter API we simply do a normal export to a temporary // file, and read the contents afterwards: tmp = File.createTempFile("jabrefCb", ".tmp"); tmp.deleteOnExit(); BibtexEntry[] bes = panel.getSelectedEntries(); HashSet<String> entries = new HashSet<String>(bes.length); for (BibtexEntry be : bes) { entries.add(be.getId()); } // Write to file: format.performExport(database, panel.metaData(), tmp.getPath(), panel.getEncoding(), entries); // Read the file and put the contents on the clipboard: StringBuilder sb = new StringBuilder(); reader = new InputStreamReader(new FileInputStream(tmp), panel.getEncoding()); int s; while ((s = reader.read()) != -1) { sb.append((char) s); } ClipboardOwner owner = new ClipboardOwner() { @Override public void lostOwnership(Clipboard clipboard, Transferable content) {} }; // StringSelection ss = new StringSelection(sw.toString()); RtfSelection rs = new RtfSelection(sb.toString()); Toolkit.getDefaultToolkit().getSystemClipboard().setContents(rs, owner); message = Localization.lang("Entries exported to clipboard") + ": " + bes.length; } catch (Exception e) { e .printStackTrace(); // To change body of catch statement use File | Settings | File // Templates. message = Localization.lang("Error exporting to clipboard"); } finally { // Clean up: if (tmp != null) { tmp.delete(); } if (reader != null) { try { reader.close(); } catch (IOException ex) { ex.printStackTrace(); } } } }
public void update() { // pdfURL = new URL("http://geog-www.sbs.ohio-state.edu/faculty/bmark/abbott_etal_ppp03.pdf"); if (result.url != null) { // System.out.println("PDF URL: "+result.url); String bibtexKey = entry.getCiteKey(); String fileDir = basePanel.metaData().getFileDirectory(GUIGlobals.FILE_FIELD); if (fileDir == null) { // TODO: error message if file dir not defined // JOptionPane.showMessageDialog(frame, Globals.lang); return; } DownloadExternalFile def = new DownloadExternalFile(basePanel.frame(), basePanel.metaData(), bibtexKey); try { def.download( result.url, new DownloadExternalFile.DownloadCallback() { public void downloadComplete(FileListEntry file) { System.out.println("finished"); FileListTableModel tm = new FileListTableModel(); String oldValue = entry.getField(GUIGlobals.FILE_FIELD); tm.setContent(oldValue); tm.addEntry(tm.getRowCount(), file); String newValue = tm.getStringRepresentation(); UndoableFieldChange edit = new UndoableFieldChange(entry, GUIGlobals.FILE_FIELD, oldValue, newValue); entry.setField(GUIGlobals.FILE_FIELD, newValue); basePanel.undoManager.addEdit(edit); basePanel.markBaseChanged(); } }); } catch (IOException e) { e.printStackTrace(); } basePanel.output(Globals.lang("Finished downloading full text document")); } else { String message = null; switch (result.status) { case FindFullText.UNKNOWN_DOMAIN: message = Globals.lang( "Unable to find full text article. No search algorithm " + "defined for the '%0' web site.", result.host); break; case FindFullText.WRONG_MIME_TYPE: message = Globals.lang( "Found pdf link, but received the wrong MIME type. " + "This could indicate that you don't have access to the fulltext article."); break; case FindFullText.LINK_NOT_FOUND: message = Globals.lang("Unable to find full text document in the linked web page."); break; case FindFullText.IO_EXCEPTION: message = Globals.lang("Connection error when trying to find full text document."); break; case FindFullText.NO_URLS_DEFINED: message = Globals.lang("This entry provides no URL or DOI links."); break; } basePanel.output(Globals.lang("Full text article download failed")); JOptionPane.showMessageDialog( basePanel.frame(), message, Globals.lang("Full text article download failed"), JOptionPane.ERROR_MESSAGE); } }