/** * Handle a List containing File objects for a set of files to import. * * @param files A List containing File instances pointing to files. * @param dropRow @param dropRow The row in the table where the files were dragged. * @return success status for the operation */ private boolean handleDraggedFiles(List<File> files, final int dropRow) { final String[] fileNames = new String[files.size()]; int i = 0; for (File file : files) { fileNames[i] = file.getAbsolutePath(); i++; } // Try to load bib files normally, and import the rest into the current // database. // This process must be spun off into a background thread: JabRefExecutorService.INSTANCE.execute( new Runnable() { @Override public void run() { final ImportPdfFilesResult importRes = new PdfImporter(frame, panel, entryTable, dropRow).importPdfFiles(fileNames, frame); if (importRes.noPdfFiles.length > 0) { loadOrImportFiles(importRes.noPdfFiles, dropRow); } } }); return true; }
@Override public void pushEntries( BibtexDatabase database, final BibtexEntry[] entries, final String keyString, MetaData metaData) { couldNotFindPipe = false; couldNotWrite = false; String lyxpipeSetting = Globals.prefs.get(JabRefPreferences.LYXPIPE); if (!lyxpipeSetting.endsWith(".in")) { lyxpipeSetting = lyxpipeSetting + ".in"; } File lp = new File(lyxpipeSetting); // this needs to fixed because it gives "asdf" when going // prefs.get("lyxpipe") if (!lp.exists() || !lp.canWrite()) { // See if it helps to append ".in": lp = new File(lyxpipeSetting + ".in"); if (!lp.exists() || !lp.canWrite()) { couldNotFindPipe = true; return; } } final File lyxpipe = lp; JabRefExecutorService.INSTANCE.executeAndWait( new Runnable() { @Override public void run() { try { FileWriter fw = new FileWriter(lyxpipe); BufferedWriter lyx_out = new BufferedWriter(fw); String citeStr; citeStr = "LYXCMD:sampleclient:citation-insert:" + keyString; lyx_out.write(citeStr + "\n"); lyx_out.close(); } catch (IOException excep) { couldNotWrite = true; } } }); }
@Override public void actionPerformed(ActionEvent arg0) { // Background this, as it takes a while. JabRefExecutorService.INSTANCE.execute( () -> { try { PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet(); pras.add(new JobName(entry.map(BibEntry::getCiteKey).orElse("NO ENTRY"), null)); previewPane.print(null, null, true, null, pras, false); } catch (PrinterException e) { // Inform the user... we don't know what to do. JOptionPane.showMessageDialog( PreviewPanel.this, Localization.lang("Could not print preview") + ".\n" + e.getMessage(), Localization.lang("Print entry preview"), JOptionPane.ERROR_MESSAGE); LOGGER.info("Could not print preview", e); } }); }
@Override public void actionPerformed(ActionEvent e) { panel = frame.getCurrentBasePanel(); // Check if a BasePanel exists: if (panel == null) { return; } // Check if any entries are selected: entries = panel.getSelectedEntries(); if (entries.length == 0) { JOptionPane.showMessageDialog( frame, Localization.lang("This operation requires one or more entries to be selected."), (String) getValue(Action.NAME), JOptionPane.ERROR_MESSAGE); return; } // If required, check that all entries have BibTeX keys defined: if (operation.requiresBibtexKeys()) { for (BibEntry entry : entries) { if ((entry.getCiteKey() == null) || entry.getCiteKey().trim().isEmpty()) { JOptionPane.showMessageDialog( frame, Localization.lang( "This operation requires all selected entries to have BibTex keys defined."), (String) getValue(Action.NAME), JOptionPane.ERROR_MESSAGE); return; } } } // All set, call the operation in a new thread: JabRefExecutorService.INSTANCE.execute(this); }
@Override public void run() { if (!goOn) { panel.output( Localization.lang("This operation requires one or more entries to be selected.")); return; } entriesChangedCount = 0; panel.frame().setProgressBarValue(0); panel.frame().setProgressBarVisible(true); int weightAutoSet = 10; // autoSet takes 10 (?) times longer than checkExisting int progressBarMax = (autoSet ? weightAutoSet * sel.size() : 0) + (checkExisting ? sel.size() : 0); panel.frame().setProgressBarMaximum(progressBarMax); int progress = 0; final NamedCompound ce = new NamedCompound(Localization.lang("Automatically set file links")); Set<BibEntry> changedEntries = new HashSet<>(); // First we try to autoset fields if (autoSet) { Collection<BibEntry> entries = new ArrayList<>(sel); // Start the automatically setting process: Runnable r = AutoSetLinks.autoSetLinks( entries, ce, changedEntries, null, panel.getBibDatabaseContext(), null, null); JabRefExecutorService.INSTANCE.executeAndWait(r); } progress += sel.size() * weightAutoSet; panel.frame().setProgressBarValue(progress); // The following loop checks all external links that are already set. if (checkExisting) { boolean removeAllBroken = false; mainLoop: for (BibEntry aSel : sel) { panel.frame().setProgressBarValue(progress++); final String old = aSel.getField(Globals.FILE_FIELD); // Check if a extension is set: if ((old != null) && !(old.isEmpty())) { FileListTableModel tableModel = new FileListTableModel(); tableModel.setContentDontGuessTypes(old); // We need to specify which directories to search in for Util.expandFilename: List<String> dirsS = panel.getBibDatabaseContext().getFileDirectory(); List<File> dirs = new ArrayList<>(); for (String dirs1 : dirsS) { dirs.add(new File(dirs1)); } for (int j = 0; j < tableModel.getRowCount(); j++) { FileListEntry flEntry = tableModel.getEntry(j); // See if the link looks like an URL: boolean httpLink = flEntry.link.toLowerCase(Locale.ENGLISH).startsWith("http"); if (httpLink) { continue; // Don't check the remote file. // TODO: should there be an option to check remote links? } // A variable to keep track of whether this link gets deleted: boolean deleted = false; // Get an absolute path representation: Optional<File> file = FileUtil.expandFilename(flEntry.link, dirsS); if ((!file.isPresent()) || !file.get().exists()) { int answer; if (removeAllBroken) { answer = 2; // We should delete this link. } else { answer = JOptionPane.showOptionDialog( panel.frame(), Localization.lang( "<HTML>Could not find file '%0'<BR>linked from entry '%1'</HTML>", flEntry.link, aSel.getCiteKey()), Localization.lang("Broken link"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, brokenLinkOptions, brokenLinkOptions[0]); } switch (answer) { case 1: // Assign new file. FileListEntryEditor flEditor = new FileListEntryEditor( panel.frame(), flEntry, false, true, panel.getBibDatabaseContext()); flEditor.setVisible(true, true); break; case 2: // Clear field: tableModel.removeEntry(j); deleted = true; // Make sure we don't investigate this link further. j--; // Step back in the iteration, because we removed an entry. break; case 3: // Clear field: tableModel.removeEntry(j); deleted = true; // Make sure we don't investigate this link further. j--; // Step back in the iteration, because we removed an entry. removeAllBroken = true; // Notify for further cases. break; default: // Cancel break mainLoop; } } // Unless we deleted this link, see if its file type is recognized: if (!deleted && flEntry.type.isPresent() && (flEntry.type.get() instanceof UnknownExternalFileType)) { String[] options = new String[] { Localization.lang("Define '%0'", flEntry.type.get().getName()), Localization.lang("Change file type"), Localization.lang("Cancel") }; String defOption = options[0]; int answer = JOptionPane.showOptionDialog( panel.frame(), Localization.lang( "One or more file links are of the type '%0', which is undefined. What do you want to do?", flEntry.type.get().getName()), Localization.lang("Undefined file type"), JOptionPane.YES_NO_CANCEL_OPTION, JOptionPane.QUESTION_MESSAGE, null, options, defOption); if (answer == JOptionPane.CANCEL_OPTION) { // User doesn't want to handle this unknown link type. } else if (answer == JOptionPane.YES_OPTION) { // User wants to define the new file type. Show the dialog: ExternalFileType newType = new ExternalFileType( flEntry.type.get().getName(), "", "", "", "new", IconTheme.JabRefIcon.FILE.getSmallIcon()); ExternalFileTypeEntryEditor editor = new ExternalFileTypeEntryEditor(panel.frame(), newType); editor.setVisible(true); if (editor.okPressed()) { // Get the old list of types, add this one, and update the list in prefs: List<ExternalFileType> fileTypes = new ArrayList<>( ExternalFileTypes.getInstance().getExternalFileTypeSelection()); fileTypes.add(newType); Collections.sort(fileTypes); ExternalFileTypes.getInstance().setExternalFileTypes(fileTypes); panel.getMainTable().repaint(); } } else { // User wants to change the type of this link. // First get a model of all file links for this entry: FileListEntryEditor editor = new FileListEntryEditor( panel.frame(), flEntry, false, true, panel.getBibDatabaseContext()); editor.setVisible(true, false); } } } if (!tableModel.getStringRepresentation().equals(old)) { // The table has been modified. Store the change: String toSet = tableModel.getStringRepresentation(); if (toSet.isEmpty()) { ce.addEdit(new UndoableFieldChange(aSel, Globals.FILE_FIELD, old, null)); aSel.clearField(Globals.FILE_FIELD); } else { ce.addEdit(new UndoableFieldChange(aSel, Globals.FILE_FIELD, old, toSet)); aSel.setField(Globals.FILE_FIELD, toSet); } changedEntries.add(aSel); } } } } if (!changedEntries.isEmpty()) { // Add the undo edit: ce.end(); panel.getUndoManager().addEdit(ce); panel.markBaseChanged(); entriesChangedCount = changedEntries.size(); } }
@Override public void pushEntries( BibDatabase database, List<BibEntry> entries, String keys, MetaData metaData) { couldNotConnect = false; couldNotCall = false; notDefined = false; initParameters(); commandPath = Globals.prefs.get(commandPathPreferenceKey); if ((commandPath == null) || commandPath.trim().isEmpty()) { notDefined = true; return; } commandPath = Globals.prefs.get(commandPathPreferenceKey); String[] addParams = Globals.prefs.get(JabRefPreferences.EMACS_ADDITIONAL_PARAMETERS).split(" "); try { String[] com = new String[addParams.length + 2]; com[0] = commandPath; System.arraycopy(addParams, 0, com, 1, addParams.length); String prefix; String suffix; if (Globals.prefs.getBoolean(JabRefPreferences.EMACS_23)) { prefix = "(with-current-buffer (window-buffer) (insert "; suffix = "))"; } else { prefix = "(insert "; suffix = ")"; } com[com.length - 1] = OS.WINDOWS ? // Windows gnuclient escaping: // java string: "(insert \\\"\\\\cite{Blah2001}\\\")"; // so cmd receives: (insert \"\\cite{Blah2001}\") // so emacs receives: (insert "\cite{Blah2001}") prefix .concat( "\\\"\\" + getCiteCommand().replaceAll("\\\\", "\\\\\\\\") + "{" + keys + "}\\\"") .concat(suffix) : // Linux gnuclient escaping: // java string: "(insert \"\\\\cite{Blah2001}\")" // so sh receives: (insert "\\cite{Blah2001}") // so emacs receives: (insert "\cite{Blah2001}") prefix .concat( "\"" + getCiteCommand().replaceAll("\\\\", "\\\\\\\\") + "{" + keys + "}\"") .concat(suffix); final Process p = Runtime.getRuntime().exec(com); Runnable errorListener = new Runnable() { @Override public void run() { try (InputStream out = p.getErrorStream()) { // try { // if (out.available() <= 0) // out = p.getInputStream(); // } catch (Exception e) { // } int c; StringBuilder sb = new StringBuilder(); try { while ((c = out.read()) != -1) { sb.append((char) c); } } catch (IOException e) { LOGGER.warn("Could not read from stderr.", e); } // Error stream has been closed. See if there were any errors: if (!sb.toString().trim().isEmpty()) { LOGGER.warn("Push to Emacs error: " + sb); couldNotConnect = true; } } catch (IOException e) { LOGGER.warn("File problem.", e); } } }; JabRefExecutorService.INSTANCE.executeAndWait(errorListener); } catch (IOException excep) { couldNotCall = true; } }