diff --git a/CHANGELOG.md b/CHANGELOG.md index 369d29a3f240..a47031a6961a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,6 +29,7 @@ We refer to [GitHub issues](https://github.com/JabRef/jabref/issues) by using `# - Fixed [#636](https://github.com/JabRef/jabref/issues/636): DOI in export filters - Fixed [#1527](https://github.com/JabRef/jabref/issues/1527): 'Get BibTeX data from DOI' Removes Marking - Fixed [#1592](https://github.com/JabRef/jabref/issues/1592): LibreOffice: wrong numbers in citation labels +- The merge entry dialog showed wrong heading after merging from DOI - Fixed [#1321](https://github.com/JabRef/jabref/issues/1321): LaTeX commands in fields not displayed in the list of references - Date fields in the BibLatex standard are now always formatted in the correct way, independent of the preferences diff --git a/build.gradle b/build.gradle index 6540c9b50295..f01b37063531 100644 --- a/build.gradle +++ b/build.gradle @@ -21,12 +21,6 @@ plugins { id 'me.champeau.gradle.jmh' version '0.3.0' } -configurations.errorprone { - // 2.0.10 does not work on Windows while 2.0.9 does - // See https://github.com/google/error-prone/issues/432 - resolutionStrategy.force 'com.google.errorprone:error_prone_core:2.0.9' -} - apply plugin: "java" apply plugin: "application" apply plugin: "project-report" diff --git a/src/main/java/net/sf/jabref/JabRefMain.java b/src/main/java/net/sf/jabref/JabRefMain.java index d55068c32453..84d87da10155 100644 --- a/src/main/java/net/sf/jabref/JabRefMain.java +++ b/src/main/java/net/sf/jabref/JabRefMain.java @@ -25,6 +25,8 @@ import net.sf.jabref.logic.exporter.ExportFormats; import net.sf.jabref.logic.journals.JournalAbbreviationLoader; import net.sf.jabref.logic.l10n.Localization; +import net.sf.jabref.logic.labelpattern.LabelPatternPreferences; +import net.sf.jabref.logic.labelpattern.LabelPatternUtil; import net.sf.jabref.logic.net.ProxyAuthenticator; import net.sf.jabref.logic.net.ProxyPreferences; import net.sf.jabref.logic.net.ProxyRegisterer; @@ -72,6 +74,9 @@ private static void start(String[] args) { // Read list(s) of journal names and abbreviations Globals.journalAbbreviationLoader = new JournalAbbreviationLoader(); + // Set key pattern based on preferences + LabelPatternUtil.updateDefaultPattern(LabelPatternPreferences.fromPreferences(Globals.prefs)); + // Check for running JabRef RemotePreferences remotePreferences = new RemotePreferences(Globals.prefs); if (remotePreferences.useRemoteServer()) { diff --git a/src/main/java/net/sf/jabref/cli/ArgumentProcessor.java b/src/main/java/net/sf/jabref/cli/ArgumentProcessor.java index 5ca302f770e9..01fbffd52abb 100644 --- a/src/main/java/net/sf/jabref/cli/ArgumentProcessor.java +++ b/src/main/java/net/sf/jabref/cli/ArgumentProcessor.java @@ -35,6 +35,7 @@ import net.sf.jabref.logic.exporter.SavePreferences; import net.sf.jabref.logic.exporter.SaveSession; import net.sf.jabref.logic.l10n.Localization; +import net.sf.jabref.logic.labelpattern.LabelPatternPreferences; import net.sf.jabref.logic.labelpattern.LabelPatternUtil; import net.sf.jabref.logic.logging.JabRefLogger; import net.sf.jabref.logic.search.DatabaseSearcher; @@ -435,7 +436,8 @@ private void regenerateBibtexKeys(List loaded) { LOGGER.info(Localization.lang("Regenerating BibTeX keys according to metadata")); for (BibEntry entry : database.getEntries()) { // try to make a new label - LabelPatternUtil.makeLabel(metaData, database, entry, Globals.prefs); + LabelPatternUtil.makeLabel(metaData, database, entry, + LabelPatternPreferences.fromPreferences(Globals.prefs)); } } else { LOGGER.info(Localization.lang("No meta data present in BIB_file. Cannot regenerate BibTeX keys")); diff --git a/src/main/java/net/sf/jabref/gui/BasePanel.java b/src/main/java/net/sf/jabref/gui/BasePanel.java index 6befb7969093..8c8a4c1b8e1f 100644 --- a/src/main/java/net/sf/jabref/gui/BasePanel.java +++ b/src/main/java/net/sf/jabref/gui/BasePanel.java @@ -116,6 +116,7 @@ import net.sf.jabref.logic.exporter.SaveSession; import net.sf.jabref.logic.l10n.Encodings; import net.sf.jabref.logic.l10n.Localization; +import net.sf.jabref.logic.labelpattern.LabelPatternPreferences; import net.sf.jabref.logic.labelpattern.LabelPatternUtil; import net.sf.jabref.logic.layout.Layout; import net.sf.jabref.logic.layout.LayoutFormatterPreferences; @@ -578,7 +579,8 @@ public void run() { // Finally, set the new keys: for (BibEntry entry : entries) { bes = entry; - LabelPatternUtil.makeLabel(bibDatabaseContext.getMetaData(), database, bes, Globals.prefs); + LabelPatternUtil.makeLabel(bibDatabaseContext.getMetaData(), database, bes, + LabelPatternPreferences.fromPreferences(Globals.prefs)); ce.addEdit(new UndoableKeyChange(database, bes, (String) oldvals.get(bes), bes.getCiteKey())); } @@ -1992,7 +1994,8 @@ public void autoGenerateKeysBeforeSaving() { for (BibEntry bes : database.getEntries()) { String oldKey = bes.getCiteKey(); if ((oldKey == null) || oldKey.isEmpty()) { - LabelPatternUtil.makeLabel(bibDatabaseContext.getMetaData(), database, bes, Globals.prefs); + LabelPatternUtil.makeLabel(bibDatabaseContext.getMetaData(), database, bes, + LabelPatternPreferences.fromPreferences(Globals.prefs)); ce.addEdit(new UndoableKeyChange(database, bes, null, bes.getCiteKey())); any = true; } diff --git a/src/main/java/net/sf/jabref/gui/EntryTypeList.java b/src/main/java/net/sf/jabref/gui/EntryTypeList.java index 5b0f8b6ebb12..02fa3687f0be 100644 --- a/src/main/java/net/sf/jabref/gui/EntryTypeList.java +++ b/src/main/java/net/sf/jabref/gui/EntryTypeList.java @@ -26,12 +26,14 @@ import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; +import net.sf.jabref.Globals; import net.sf.jabref.logic.l10n.Localization; import net.sf.jabref.logic.labelpattern.LabelPatternUtil; import net.sf.jabref.model.EntryTypes; import net.sf.jabref.model.database.BibDatabaseMode; import net.sf.jabref.model.entry.CustomEntryType; import net.sf.jabref.model.entry.EntryType; +import net.sf.jabref.preferences.JabRefPreferences; /** * This class extends FieldSetComponent to provide some required functionality for the @@ -70,7 +72,8 @@ protected void addField(String str) { return; } - String testString = LabelPatternUtil.checkLegalKey(s); + String testString = LabelPatternUtil.checkLegalKey(s, + Globals.prefs.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY)); if (!testString.equals(s) || (s.indexOf('&') >= 0)) { // Report error and exit. JOptionPane.showMessageDialog(this, Localization.lang("Entry type names are not allowed to contain white space or the following " diff --git a/src/main/java/net/sf/jabref/gui/FieldSetComponent.java b/src/main/java/net/sf/jabref/gui/FieldSetComponent.java index 992f3e3fd701..d48a565b9694 100644 --- a/src/main/java/net/sf/jabref/gui/FieldSetComponent.java +++ b/src/main/java/net/sf/jabref/gui/FieldSetComponent.java @@ -46,8 +46,10 @@ import javax.swing.event.ListDataListener; import javax.swing.event.ListSelectionListener; +import net.sf.jabref.Globals; import net.sf.jabref.logic.l10n.Localization; import net.sf.jabref.logic.labelpattern.LabelPatternUtil; +import net.sf.jabref.preferences.JabRefPreferences; /** * @author alver @@ -249,7 +251,8 @@ protected void addField(String str) { return; } - String testString = LabelPatternUtil.checkLegalKey(s); + String testString = LabelPatternUtil.checkLegalKey(s, + Globals.prefs.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY)); if (!testString.equals(s) || (s.indexOf('&') >= 0)) { // Report error and exit. JOptionPane.showMessageDialog(this, Localization.lang("Field names are not allowed to contain white space or the following " diff --git a/src/main/java/net/sf/jabref/gui/GenFieldsCustomizer.java b/src/main/java/net/sf/jabref/gui/GenFieldsCustomizer.java index 80b76812e7c2..80781abf51d5 100644 --- a/src/main/java/net/sf/jabref/gui/GenFieldsCustomizer.java +++ b/src/main/java/net/sf/jabref/gui/GenFieldsCustomizer.java @@ -136,7 +136,8 @@ private void okActionPerformed() { Localization.lang("Error"), JOptionPane.ERROR_MESSAGE); return; } - String testString = LabelPatternUtil.checkLegalKey(parts[1]); + String testString = LabelPatternUtil.checkLegalKey(parts[1], + Globals.prefs.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY)); if (!testString.equals(parts[1]) || (parts[1].indexOf('&') >= 0)) { // Report error and exit. JOptionPane.showMessageDialog(this, Localization.lang("Field names are not allowed to contain white space or the following " diff --git a/src/main/java/net/sf/jabref/gui/ImportInspectionDialog.java b/src/main/java/net/sf/jabref/gui/ImportInspectionDialog.java index a026e7363c37..bf08306974d4 100644 --- a/src/main/java/net/sf/jabref/gui/ImportInspectionDialog.java +++ b/src/main/java/net/sf/jabref/gui/ImportInspectionDialog.java @@ -91,6 +91,7 @@ import net.sf.jabref.logic.groups.GroupTreeNode; import net.sf.jabref.logic.help.HelpFile; import net.sf.jabref.logic.l10n.Localization; +import net.sf.jabref.logic.labelpattern.LabelPatternPreferences; import net.sf.jabref.logic.labelpattern.LabelPatternUtil; import net.sf.jabref.logic.util.UpdateField; import net.sf.jabref.model.DuplicateCheck; @@ -461,7 +462,8 @@ private void generateKeySelectedEntry() { database.insertEntry(entry); // Generate a unique key: - LabelPatternUtil.makeLabel(localMetaData, database, entry, Globals.prefs); + LabelPatternUtil.makeLabel(localMetaData, database, entry, + LabelPatternPreferences.fromPreferences(Globals.prefs)); // Remove the entry from the database again, since we only added it in // order to // make sure the key was unique: @@ -502,7 +504,8 @@ private void generateKeys() { entry.setId(IdGenerator.next()); database.insertEntry(entry); - LabelPatternUtil.makeLabel(localMetaData, database, entry, Globals.prefs); + LabelPatternUtil.makeLabel(localMetaData, database, entry, + LabelPatternPreferences.fromPreferences(Globals.prefs)); // Add the generated key to our list: keys.add(entry.getCiteKey()); } diff --git a/src/main/java/net/sf/jabref/gui/entryeditor/EntryEditor.java b/src/main/java/net/sf/jabref/gui/entryeditor/EntryEditor.java index bdf8892c747a..ed14aaba325d 100644 --- a/src/main/java/net/sf/jabref/gui/entryeditor/EntryEditor.java +++ b/src/main/java/net/sf/jabref/gui/entryeditor/EntryEditor.java @@ -98,6 +98,7 @@ import net.sf.jabref.logic.bibtex.LatexFieldFormatterPreferences; import net.sf.jabref.logic.help.HelpFile; import net.sf.jabref.logic.l10n.Localization; +import net.sf.jabref.logic.labelpattern.LabelPatternPreferences; import net.sf.jabref.logic.labelpattern.LabelPatternUtil; import net.sf.jabref.logic.search.SearchQueryHighlightListener; import net.sf.jabref.logic.util.date.TimeStamp; @@ -1102,7 +1103,8 @@ public void actionPerformed(ActionEvent event) { } // Make sure the key is legal: - String cleaned = LabelPatternUtil.checkLegalKey(newValue); + String cleaned = LabelPatternUtil.checkLegalKey(newValue, + Globals.prefs.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY)); if ((cleaned == null) || cleaned.equals(newValue)) { textField.setValidBackgroundColor(); } else { @@ -1369,7 +1371,7 @@ public void actionPerformed(ActionEvent e) { } LabelPatternUtil.makeLabel(panel.getBibDatabaseContext().getMetaData(), panel.getDatabase(), entry, - Globals.prefs); + LabelPatternPreferences.fromPreferences(Globals.prefs)); // Store undo information: panel.getUndoManager().addEdit(new UndoableKeyChange(panel.getDatabase(), entry, (String) oldValue, entry.getCiteKey())); diff --git a/src/main/java/net/sf/jabref/gui/labelpattern/SearchFixDuplicateLabels.java b/src/main/java/net/sf/jabref/gui/labelpattern/SearchFixDuplicateLabels.java index 930b0e770ef0..515b89f173fa 100644 --- a/src/main/java/net/sf/jabref/gui/labelpattern/SearchFixDuplicateLabels.java +++ b/src/main/java/net/sf/jabref/gui/labelpattern/SearchFixDuplicateLabels.java @@ -28,6 +28,7 @@ import net.sf.jabref.gui.undo.UndoableKeyChange; import net.sf.jabref.gui.worker.AbstractWorker; import net.sf.jabref.logic.l10n.Localization; +import net.sf.jabref.logic.labelpattern.LabelPatternPreferences; import net.sf.jabref.logic.labelpattern.LabelPatternUtil; import net.sf.jabref.model.database.BibDatabase; import net.sf.jabref.model.entry.BibEntry; @@ -111,7 +112,7 @@ public void update() { for (BibEntry entry : toGenerateFor) { String oldKey = entry.getCiteKey(); LabelPatternUtil.makeLabel(panel.getBibDatabaseContext().getMetaData(), panel.getDatabase(), entry, - Globals.prefs); + LabelPatternPreferences.fromPreferences(Globals.prefs)); ce.addEdit(new UndoableKeyChange(panel.getDatabase(), entry, oldKey, entry.getCiteKey())); } ce.end(); diff --git a/src/main/java/net/sf/jabref/gui/mergeentries/MergeEntries.java b/src/main/java/net/sf/jabref/gui/mergeentries/MergeEntries.java index 7d15dd53d13a..4a7a38c38a20 100644 --- a/src/main/java/net/sf/jabref/gui/mergeentries/MergeEntries.java +++ b/src/main/java/net/sf/jabref/gui/mergeentries/MergeEntries.java @@ -19,6 +19,7 @@ import java.io.IOException; import java.io.StringWriter; import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; import java.util.HashMap; import java.util.HashSet; @@ -39,11 +40,10 @@ import javax.swing.JTextArea; import javax.swing.JTextPane; import javax.swing.SwingUtilities; -import javax.swing.text.html.HTMLEditorKit; -import javax.swing.text.html.StyleSheet; import net.sf.jabref.Globals; import net.sf.jabref.gui.PreviewPanel; +import net.sf.jabref.gui.util.component.DiffHighlightingTextPane; import net.sf.jabref.logic.bibtex.BibEntryWriter; import net.sf.jabref.logic.bibtex.LatexFieldFormatter; import net.sf.jabref.logic.bibtex.LatexFieldFormatterPreferences; @@ -72,29 +72,20 @@ public class MergeEntries { private static final Log LOGGER = LogFactory.getLog(MergeEntries.class); - private static final String CONTENT_TYPE = "text/html"; - // Headings - private static final String[] COLUMN_HEADINGS = {Localization.lang("Field"), + private final List columnHeadings = Arrays.asList(Localization.lang("Field"), Localization.lang("Left entry"), Localization.lang("Left"), Localization.lang("None"), Localization.lang("Right"), - Localization.lang("Right entry")}; + Localization.lang("Right entry")); private static final String[] DIFF_MODES = {Localization.lang("Plain text"), Localization.lang("Show diff") + " - " + Localization.lang("word"), Localization.lang("Show diff") + " - " + Localization.lang("character"), Localization.lang("Show symmetric diff") + " - " + Localization.lang("word"), Localization.lang("Show symmetric diff") + " - " + Localization.lang("character")}; - private static final String HTML_START = ""; - private static final String HTML_END = ""; - private static final String BODY_STYLE = "body{font:sans-serif}"; - private static final String ADDITION_STYLE = ".add{color:blue;text-decoration:underline}"; - private static final String REMOVAL_STYLE = ".del{color:red;text-decoration:line-through;}"; - private static final String CHANGE_STYLE = ".change{color:#006400;text-decoration:underline}"; - private final Set identicalFields = new HashSet<>(); private final Set differentFields = new HashSet<>(); private final BibEntry mergedEntry = new BibEntry(); @@ -117,6 +108,11 @@ public class MergeEntries { private static final String MARGIN = "10px"; + private static final List HEADING_LABELS = new ArrayList<>(6); + + private static final CellConstraints CELL_CONSTRAINTS = new CellConstraints(); + + /** * Constructor taking two entries @@ -142,8 +138,8 @@ public MergeEntries(BibEntry entryLeft, BibEntry entryRight, BibDatabaseMode typ * @param type Bib database mode */ public MergeEntries(BibEntry entryLeft, BibEntry entryRight, String headingLeft, String headingRight, BibDatabaseMode type) { - COLUMN_HEADINGS[1] = headingLeft; - COLUMN_HEADINGS[5] = headingRight; + columnHeadings.set(1, headingLeft); + columnHeadings.set(5, headingRight); this.leftEntry = entryLeft; this.rightEntry = entryRight; @@ -159,16 +155,7 @@ private void initialize() { doneBuilding = false; setupFields(); - // Fill diff mode combo box - for (String diffText : DIFF_MODES) { - diffMode.addItem(diffText); - } - diffMode.setSelectedIndex( - Math.min(Globals.prefs.getInt(JabRefPreferences.MERGE_ENTRIES_DIFF_MODE), diffMode.getItemCount() - 1)); - diffMode.addActionListener(e -> { - updateTextPanes(differentFields); - storePreference(); - }); + fillDiffModes(); // Create main layout String colSpecMain = "left:pref, 5px, center:3cm:grow, 5px, center:pref, 3px, center:pref, 3px, center:pref, 5px, center:3cm:grow"; @@ -186,52 +173,62 @@ private void initialize() { mainPanel.setLayout(mainLayout); mergePanel.setLayout(mergeLayout); - CellConstraints cc = new CellConstraints(); + setupHeadingRows(); - mainPanel.add(boldFontLabel(Localization.lang("Use")), cc.xyw(4, 1, 7, "center, bottom")); - mainPanel.add(diffMode, cc.xy(11, 1, "right, bottom")); + mainPanel.add(new JSeparator(), CELL_CONSTRAINTS.xyw(1, 3, 11)); - // Set headings - JLabel[] headingLabels = new JLabel[6]; - for (int i = 0; i < 6; i++) { - headingLabels[i] = boldFontLabel(COLUMN_HEADINGS[i]); - mainPanel.add(headingLabels[i], cc.xy(1 + (i * 2), 2)); + setupEntryTypeRow(mergePanel); - } + int maxLabelWidth = setupFieldRows(mergePanel); - mainPanel.add(new JSeparator(), cc.xyw(1, 3, 11)); - // Start with entry type - mergePanel.add(boldFontLabel(Localization.lang("Entry type")), cc.xy(1, 1)); + // Create and add scrollpane + scrollPane = new JScrollPane(mergePanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, + JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); + scrollPane.setBorder(BorderFactory.createEmptyBorder()); + updateTextPanes(allFields); + mainPanel.add(scrollPane, CELL_CONSTRAINTS.xyw(1, 4, 11)); + mainPanel.add(new JSeparator(), CELL_CONSTRAINTS.xyw(1, 5, 11)); - JTextPane leftTypeDisplay = getStyledTextPane(); - leftTypeDisplay.setText(HTML_START + leftEntry.getType() + HTML_END); - mergePanel.add(leftTypeDisplay, cc.xy(3, 1)); - if (leftEntry.getType().equals(rightEntry.getType())) { - identicalTypes = true; - } else { - identicalTypes = false; - ButtonGroup group = new ButtonGroup(); - typeRadioButtons = new ArrayList<>(2); - for (int k = 0; k < 3; k += 2) { - JRadioButton button = new JRadioButton(); - typeRadioButtons.add(button); - group.add(button); - mergePanel.add(button, cc.xy(5 + (k * 2), 1)); - button.addChangeListener(e -> updateAll()); - } - typeRadioButtons.get(0).setSelected(true); - } - JTextPane rightTypeDisplay = getStyledTextPane(); - rightTypeDisplay.setText(HTML_START + rightEntry.getType() + HTML_END); - mergePanel.add(rightTypeDisplay, cc.xy(11, 1)); + synchronizeColumnWidths(mainLayout, mergeLayout, maxLabelWidth); + + // Setup a PreviewPanel and a Bibtex source box for the merged entry + mainPanel.add(boldFontLabel(Localization.lang("Merged entry")), CELL_CONSTRAINTS.xyw(1, 6, 6)); + + entryPreview = new PreviewPanel(null, mergedEntry, null, Globals.prefs.get(JabRefPreferences.PREVIEW_0)); + mainPanel.add(entryPreview, CELL_CONSTRAINTS.xyw(1, 8, 6)); + + mainPanel.add(boldFontLabel(Localization.lang("Merged BibTeX source code")), CELL_CONSTRAINTS.xyw(8, 6, 4)); + + sourceView = new JTextArea(); + sourceView.setLineWrap(true); + sourceView.setFont(new Font("Monospaced", Font.PLAIN, Globals.prefs.getInt(JabRefPreferences.FONT_SIZE))); + mainPanel.add(new JScrollPane(sourceView), CELL_CONSTRAINTS.xyw(8, 8, 4)); + sourceView.setEditable(false); + // Add some margin around the layout + mainLayout.appendRow(RowSpec.decode(MARGIN)); + mainLayout.appendColumn(ColumnSpec.decode(MARGIN)); + mainLayout.insertRow(1, RowSpec.decode(MARGIN)); + mainLayout.insertColumn(1, ColumnSpec.decode(MARGIN)); + + // Everything done, allow any action to actually update the merged entry + doneBuilding = true; + + updateAll(); + + // Show what we've got + mainPanel.setVisible(true); + SwingUtilities.invokeLater(() -> scrollPane.getVerticalScrollBar().setValue(0)); + } + + private int setupFieldRows(JPanel mergePanel) { // For all fields in joint add a row and possibly radio buttons int row = 2; int maxLabelWidth = -1; for (String field : allFields) { JLabel label = boldFontLabel(new SentenceCaseFormatter().format(field)); - mergePanel.add(label, cc.xy(1, (2 * row) - 1, "left, top")); + mergePanel.add(label, CELL_CONSTRAINTS.xy(1, (2 * row) - 1, "left, top")); Optional leftString = leftEntry.getFieldOptional(field); Optional rightString = rightEntry.getFieldOptional(field); if (leftString.equals(rightString)) { @@ -244,8 +241,8 @@ private void initialize() { // Left text pane if (leftString.isPresent()) { - JTextPane tf = getStyledTextPane(); - mergePanel.add(tf, cc.xy(3, (2 * row) - 1, "f, f")); + JTextPane tf = new DiffHighlightingTextPane(); + mergePanel.add(tf, CELL_CONSTRAINTS.xy(3, (2 * row) - 1, "f, f")); leftTextPanes.put(field, tf); } @@ -258,7 +255,7 @@ private void initialize() { for (int k = 0; k < 3; k++) { JRadioButton button = new JRadioButton(); group.add(button); - mergePanel.add(button, cc.xy(5 + (k * 2), (2 * row) - 1)); + mergePanel.add(button, CELL_CONSTRAINTS.xy(5 + (k * 2), (2 * row) - 1)); button.addChangeListener(e -> updateAll()); list.add(button); } @@ -276,60 +273,78 @@ private void initialize() { // Right text pane if (rightString.isPresent()) { - JTextPane tf = getStyledTextPane(); - mergePanel.add(tf, cc.xy(11, (2 * row) - 1, "f, f")); + JTextPane tf = new DiffHighlightingTextPane(); + mergePanel.add(tf, CELL_CONSTRAINTS.xy(11, (2 * row) - 1, "f, f")); rightTextPanes.put(field, tf); } row++; } + return maxLabelWidth; + } + + private void setupEntryTypeRow(JPanel mergePanel) { + // Start with entry type + mergePanel.add(boldFontLabel(Localization.lang("Entry type")), CELL_CONSTRAINTS.xy(1, 1)); + + JTextPane leftTypeDisplay = new DiffHighlightingTextPane(); + leftTypeDisplay.setText(DiffHighlighting.HTML_START + leftEntry.getType() + DiffHighlighting.HTML_END); + mergePanel.add(leftTypeDisplay, CELL_CONSTRAINTS.xy(3, 1)); + if (leftEntry.getType().equals(rightEntry.getType())) { + identicalTypes = true; + } else { + identicalTypes = false; + ButtonGroup group = new ButtonGroup(); + typeRadioButtons = new ArrayList<>(2); + for (int k = 0; k < 3; k += 2) { + JRadioButton button = new JRadioButton(); + typeRadioButtons.add(button); + group.add(button); + mergePanel.add(button, CELL_CONSTRAINTS.xy(5 + (k * 2), 1)); + button.addChangeListener(e -> updateAll()); + } + typeRadioButtons.get(0).setSelected(true); + } + JTextPane rightTypeDisplay = new DiffHighlightingTextPane(); + rightTypeDisplay.setText(DiffHighlighting.HTML_START + rightEntry.getType() + DiffHighlighting.HTML_END); + mergePanel.add(rightTypeDisplay, CELL_CONSTRAINTS.xy(11, 1)); + } + private void setupHeadingRows() { + mainPanel.add(boldFontLabel(Localization.lang("Use")), CELL_CONSTRAINTS.xyw(4, 1, 7, "center, bottom")); + mainPanel.add(diffMode, CELL_CONSTRAINTS.xy(11, 1, "right, bottom")); - scrollPane = new JScrollPane(mergePanel, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED, - JScrollPane.HORIZONTAL_SCROLLBAR_NEVER); - scrollPane.setBorder(BorderFactory.createEmptyBorder()); - updateTextPanes(allFields); - mainPanel.add(scrollPane, cc.xyw(1, 4, 11)); - mainPanel.add(new JSeparator(), cc.xyw(1, 5, 11)); + // Set headings + for (int i = 0; i < 6; i++) { + HEADING_LABELS.add(boldFontLabel(columnHeadings.get(i))); + mainPanel.add(HEADING_LABELS.get(i), CELL_CONSTRAINTS.xy(1 + (i * 2), 2)); + } + } + private void fillDiffModes() { + // Fill diff mode combo box + for (String diffText : DIFF_MODES) { + diffMode.addItem(diffText); + } + diffMode.setSelectedIndex( + Math.min(Globals.prefs.getInt(JabRefPreferences.MERGE_ENTRIES_DIFF_MODE), diffMode.getItemCount() - 1)); + diffMode.addActionListener(e -> { + updateTextPanes(differentFields); + storePreference(); + }); + } + + private void synchronizeColumnWidths(FormLayout mainLayout, FormLayout mergeLayout, + int maxLabelWidth) { // Synchronize column widths String[] rbAlign = {"right", "center", "left"}; mainLayout.setColumnSpec(1, ColumnSpec.decode(Integer.toString(maxLabelWidth) + "px")); Integer maxRBWidth = -1; for (int k = 2; k < 5; k++) { - maxRBWidth = Math.max(maxRBWidth, headingLabels[k].getPreferredSize().width); + maxRBWidth = Math.max(maxRBWidth, HEADING_LABELS.get(k).getPreferredSize().width); } for (int k = 0; k < 3; k++) { mergeLayout.setColumnSpec(5 + (k * 2), ColumnSpec.decode(rbAlign[k] + ":" + maxRBWidth + "px")); } - - // Setup a PreviewPanel and a Bibtex source box for the merged entry - mainPanel.add(boldFontLabel(Localization.lang("Merged entry")), cc.xyw(1, 6, 6)); - - entryPreview = new PreviewPanel(null, mergedEntry, null, Globals.prefs.get(JabRefPreferences.PREVIEW_0)); - mainPanel.add(entryPreview, cc.xyw(1, 8, 6)); - - mainPanel.add(boldFontLabel(Localization.lang("Merged BibTeX source code")), cc.xyw(8, 6, 4)); - - sourceView = new JTextArea(); - sourceView.setLineWrap(true); - sourceView.setFont(new Font("Monospaced", Font.PLAIN, Globals.prefs.getInt(JabRefPreferences.FONT_SIZE))); - mainPanel.add(new JScrollPane(sourceView), cc.xyw(8, 8, 4)); - sourceView.setEditable(false); - - // Add some margin around the layout - mainLayout.appendRow(RowSpec.decode(MARGIN)); - mainLayout.appendColumn(ColumnSpec.decode(MARGIN)); - mainLayout.insertRow(1, RowSpec.decode(MARGIN)); - mainLayout.insertColumn(1, ColumnSpec.decode(MARGIN)); - - // Everything done, allow any action to actually update the merged entry - doneBuilding = true; - - updateAll(); - - // Show what we've got - mainPanel.setVisible(true); - javax.swing.SwingUtilities.invokeLater(() -> scrollPane.getVerticalScrollBar().setValue(0)); } private JLabel boldFontLabel(String text) { @@ -385,27 +400,16 @@ private void updateTextPanes(Collection fields) { break; } if ((leftString != null) && leftTextPanes.containsKey(field)) { - leftTextPanes.get(field).setText(HTML_START + leftString + HTML_END); + leftTextPanes.get(field).setText(DiffHighlighting.HTML_START + leftString + DiffHighlighting.HTML_END); } if ((rightString != null) && rightTextPanes.containsKey(field)) { - rightTextPanes.get(field).setText(HTML_START + rightString + HTML_END); + rightTextPanes.get(field).setText(DiffHighlighting.HTML_START + rightString + DiffHighlighting.HTML_END); } } SwingUtilities.invokeLater(() -> scrollPane.getVerticalScrollBar() .setValue(Math.min(scrollPane.getVerticalScrollBar().getMaximum(), oldScrollPaneValue))); } - private JTextPane getStyledTextPane() { - JTextPane pane = new JTextPane(); - pane.setContentType(CONTENT_TYPE); - StyleSheet sheet = ((HTMLEditorKit) pane.getEditorKit()).getStyleSheet(); - sheet.addRule(BODY_STYLE); - sheet.addRule(ADDITION_STYLE); - sheet.addRule(REMOVAL_STYLE); - sheet.addRule(CHANGE_STYLE); - pane.setEditable(false); - return pane; - } /** * @return Merged BibEntry diff --git a/src/main/java/net/sf/jabref/gui/preftabs/LabelPatternPrefTab.java b/src/main/java/net/sf/jabref/gui/preftabs/LabelPatternPrefTab.java index ba31351b58a0..c48c6c4b9258 100644 --- a/src/main/java/net/sf/jabref/gui/preftabs/LabelPatternPrefTab.java +++ b/src/main/java/net/sf/jabref/gui/preftabs/LabelPatternPrefTab.java @@ -29,6 +29,7 @@ import net.sf.jabref.gui.labelpattern.LabelPatternPanel; import net.sf.jabref.logic.l10n.Localization; import net.sf.jabref.logic.labelpattern.GlobalLabelPattern; +import net.sf.jabref.logic.labelpattern.LabelPatternPreferences; import net.sf.jabref.logic.labelpattern.LabelPatternUtil; import net.sf.jabref.preferences.JabRefPreferences; @@ -90,7 +91,7 @@ public void storeSettings() { Globals.prefs.putBoolean(JabRefPreferences.KEY_GEN_ALWAYS_ADD_LETTER, false); } - LabelPatternUtil.updateDefaultPattern(); + LabelPatternUtil.updateDefaultPattern(LabelPatternPreferences.fromPreferences(Globals.prefs)); // fetch entries from GUI GlobalLabelPattern keypatterns = getLabelPatternAsGlobalLabelPattern(); diff --git a/src/main/java/net/sf/jabref/gui/util/component/DiffHighlightingTextPane.java b/src/main/java/net/sf/jabref/gui/util/component/DiffHighlightingTextPane.java new file mode 100644 index 000000000000..dcca26b4d8b8 --- /dev/null +++ b/src/main/java/net/sf/jabref/gui/util/component/DiffHighlightingTextPane.java @@ -0,0 +1,28 @@ +package net.sf.jabref.gui.util.component; + +import javax.swing.JTextPane; +import javax.swing.text.html.HTMLEditorKit; +import javax.swing.text.html.StyleSheet; + +public class DiffHighlightingTextPane extends JTextPane { + + private static final String BODY_STYLE = "body{font:sans-serif}"; + private static final String ADDITION_STYLE = ".add{color:blue;text-decoration:underline}"; + private static final String REMOVAL_STYLE = ".del{color:red;text-decoration:line-through;}"; + private static final String CHANGE_STYLE = ".change{color:#006400;text-decoration:underline}"; + + private static final String CONTENT_TYPE = "text/html"; + + + public DiffHighlightingTextPane() { + super(); + setContentType(CONTENT_TYPE); + StyleSheet sheet = ((HTMLEditorKit) getEditorKit()).getStyleSheet(); + sheet.addRule(BODY_STYLE); + sheet.addRule(ADDITION_STYLE); + sheet.addRule(REMOVAL_STYLE); + sheet.addRule(CHANGE_STYLE); + setEditable(false); + } + +} diff --git a/src/main/java/net/sf/jabref/importer/fileformat/EndnoteImporter.java b/src/main/java/net/sf/jabref/importer/fileformat/EndnoteImporter.java index f5b0d9654839..916b2a4013ce 100644 --- a/src/main/java/net/sf/jabref/importer/fileformat/EndnoteImporter.java +++ b/src/main/java/net/sf/jabref/importer/fileformat/EndnoteImporter.java @@ -24,11 +24,13 @@ import java.util.Map; import java.util.regex.Pattern; +import net.sf.jabref.Globals; import net.sf.jabref.importer.ParserResult; import net.sf.jabref.logic.labelpattern.LabelPatternUtil; import net.sf.jabref.model.entry.AuthorList; import net.sf.jabref.model.entry.BibEntry; import net.sf.jabref.model.entry.FieldName; +import net.sf.jabref.preferences.JabRefPreferences; /** * Importer for the Refer/Endnote format. @@ -236,7 +238,8 @@ else if ("P".equals(prefix)) { type = "mastersthesis"; } } else if ("F".equals(prefix)) { - hm.put(BibEntry.KEY_FIELD, LabelPatternUtil.checkLegalKey(val)); + hm.put(BibEntry.KEY_FIELD, LabelPatternUtil.checkLegalKey(val, + Globals.prefs.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY))); } } diff --git a/src/main/java/net/sf/jabref/importer/fileformat/FreeCiteImporter.java b/src/main/java/net/sf/jabref/importer/fileformat/FreeCiteImporter.java index bdc6cac0805f..5bd6d96dc6e7 100644 --- a/src/main/java/net/sf/jabref/importer/fileformat/FreeCiteImporter.java +++ b/src/main/java/net/sf/jabref/importer/fileformat/FreeCiteImporter.java @@ -39,6 +39,7 @@ import net.sf.jabref.JabRefGUI; import net.sf.jabref.importer.ParserResult; import net.sf.jabref.logic.l10n.Localization; +import net.sf.jabref.logic.labelpattern.LabelPatternPreferences; import net.sf.jabref.logic.labelpattern.LabelPatternUtil; import net.sf.jabref.logic.util.OS; import net.sf.jabref.model.entry.BibEntry; @@ -217,7 +218,8 @@ public ParserResult importEntries(String text) { // autogenerate label (BibTeX key) LabelPatternUtil.makeLabel( JabRefGUI.getMainFrame().getCurrentBasePanel().getBibDatabaseContext().getMetaData(), - JabRefGUI.getMainFrame().getCurrentBasePanel().getDatabase(), e, Globals.prefs); + JabRefGUI.getMainFrame().getCurrentBasePanel().getDatabase(), e, + LabelPatternPreferences.fromPreferences(Globals.prefs)); res.add(e); } diff --git a/src/main/java/net/sf/jabref/logic/labelpattern/LabelPatternPreferences.java b/src/main/java/net/sf/jabref/logic/labelpattern/LabelPatternPreferences.java new file mode 100644 index 000000000000..74c204d6dcae --- /dev/null +++ b/src/main/java/net/sf/jabref/logic/labelpattern/LabelPatternPreferences.java @@ -0,0 +1,56 @@ +package net.sf.jabref.logic.labelpattern; + +import net.sf.jabref.preferences.JabRefPreferences; + +public class LabelPatternPreferences { + + private final String defaultLabelPattern; + private final String keyPatternRegex; + private final String keyPatternReplacement; + private final boolean alwaysAddLetter; + private final boolean firstLetterA; + private final boolean enforceLegalKey; + + public LabelPatternPreferences(String defaultLabelPattern, String keyPatternRegex, String keyPatternReplacement, + boolean alwaysAddLetter, boolean firstLetterA, boolean enforceLegalKey) { + this.defaultLabelPattern = defaultLabelPattern; + this.keyPatternRegex = keyPatternRegex; + this.keyPatternReplacement = keyPatternReplacement; + this.alwaysAddLetter = alwaysAddLetter; + this.firstLetterA = firstLetterA; + this.enforceLegalKey = enforceLegalKey; + } + + public static LabelPatternPreferences fromPreferences(JabRefPreferences jabRefPreferences) { + return new LabelPatternPreferences(jabRefPreferences.get(JabRefPreferences.DEFAULT_LABEL_PATTERN), + jabRefPreferences.get(JabRefPreferences.KEY_PATTERN_REGEX), + jabRefPreferences.get(JabRefPreferences.KEY_PATTERN_REPLACEMENT), + jabRefPreferences.getBoolean(JabRefPreferences.KEY_GEN_ALWAYS_ADD_LETTER), + jabRefPreferences.getBoolean(JabRefPreferences.KEY_GEN_FIRST_LETTER_A), + jabRefPreferences.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY)); + } + + public String getDefaultLabelPattern() { + return defaultLabelPattern; + } + + public String getKeyPatternRegex() { + return keyPatternRegex; + } + + public String getKeyPatternReplacement() { + return keyPatternReplacement; + } + + public boolean isAlwaysAddLetter() { + return alwaysAddLetter; + } + + public boolean isFirstLetterA() { + return firstLetterA; + } + + public boolean isEnforceLegalKey() { + return enforceLegalKey; + } +} diff --git a/src/main/java/net/sf/jabref/logic/labelpattern/LabelPatternUtil.java b/src/main/java/net/sf/jabref/logic/labelpattern/LabelPatternUtil.java index 507d422a68a4..57c7cb557d73 100644 --- a/src/main/java/net/sf/jabref/logic/labelpattern/LabelPatternUtil.java +++ b/src/main/java/net/sf/jabref/logic/labelpattern/LabelPatternUtil.java @@ -34,7 +34,6 @@ import net.sf.jabref.model.entry.AuthorList; import net.sf.jabref.model.entry.BibEntry; import net.sf.jabref.model.entry.FieldName; -import net.sf.jabref.preferences.JabRefPreferences; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -58,16 +57,12 @@ public class LabelPatternUtil { private static final int CHARS_OF_FIRST = 5; - - static { - updateDefaultPattern(); - } - private static BibDatabase database; - public static void updateDefaultPattern() { + + public static void updateDefaultPattern(LabelPatternPreferences labelPatternPreferences) { defaultLabelPattern = LabelPatternUtil - .split(JabRefPreferences.getInstance().get(JabRefPreferences.DEFAULT_LABEL_PATTERN)); + .split(labelPatternPreferences.getDefaultLabelPattern()); } /** @@ -427,7 +422,8 @@ public static List split(String labelPattern) { * @param entry a BibEntry * @return modified BibEntry */ - public static void makeLabel(MetaData metaData, BibDatabase dBase, BibEntry entry, JabRefPreferences prefs) { + public static void makeLabel(MetaData metaData, BibDatabase dBase, BibEntry entry, + LabelPatternPreferences labelPatternPreferences) { database = dBase; String key; StringBuilder stringBuilder = new StringBuilder(); @@ -471,12 +467,12 @@ public static void makeLabel(MetaData metaData, BibDatabase dBase, BibEntry entr } // Remove all illegal characters from the key. - key = checkLegalKey(stringBuilder.toString()); + key = checkLegalKey(stringBuilder.toString(), labelPatternPreferences.isEnforceLegalKey()); // Remove Regular Expressions while generating Keys - String regex = prefs.get(JabRefPreferences.KEY_PATTERN_REGEX); + String regex = labelPatternPreferences.getKeyPatternRegex(); if ((regex != null) && !regex.trim().isEmpty()) { - String replacement = prefs.get(JabRefPreferences.KEY_PATTERN_REPLACEMENT); + String replacement = labelPatternPreferences.getKeyPatternReplacement(); key = key.replaceAll(regex, replacement); } @@ -494,8 +490,8 @@ public static void makeLabel(MetaData metaData, BibDatabase dBase, BibEntry entr occurrences--; // No change, so we can accept one dupe. } - boolean alwaysAddLetter = prefs.getBoolean(JabRefPreferences.KEY_GEN_ALWAYS_ADD_LETTER); - boolean firstLetterA = prefs.getBoolean(JabRefPreferences.KEY_GEN_FIRST_LETTER_A); + boolean alwaysAddLetter = labelPatternPreferences.isAlwaysAddLetter(); + boolean firstLetterA = labelPatternPreferences.isFirstLetterA(); if (!alwaysAddLetter && (occurrences == 0)) { // No dupes found, so we can just go ahead. @@ -1380,21 +1376,6 @@ private static String[] parseFieldMarker(String arg) { return parts.toArray(new String[parts.size()]); } - /** - * This method returns a String similar to the one passed in, except that it is molded into a form that is - * acceptable for bibtex. - *

- * Watch-out that the returned string might be of length 0 afterwards. - * - * @param key mayBeNull - */ - public static String checkLegalKey(String key) { - if (key == null) { - return null; - } - return checkLegalKey(key, - JabRefPreferences.getInstance().getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY)); - } /** * This method returns a String similar to the one passed in, except that it is molded into a form that is diff --git a/src/main/java/net/sf/jabref/logic/util/strings/DiffHighlighting.java b/src/main/java/net/sf/jabref/logic/util/strings/DiffHighlighting.java index c653d86f9298..ba6463b1f69e 100644 --- a/src/main/java/net/sf/jabref/logic/util/strings/DiffHighlighting.java +++ b/src/main/java/net/sf/jabref/logic/util/strings/DiffHighlighting.java @@ -16,6 +16,10 @@ public class DiffHighlighting { private static final String CHANGE_START = ""; private static final String TAG_END = ""; + public static final String HTML_START = ""; + public static final String HTML_END = ""; + + public static String generateDiffHighlighting(String baseString, String modifiedString, String separator) { Objects.requireNonNull(separator); if ((baseString != null) && (modifiedString != null)) { @@ -94,5 +98,4 @@ public static String generateSymmetricHighlighting(String baseString, String mod return modifiedString; } - } diff --git a/src/main/java/net/sf/jabref/pdfimport/PdfImporter.java b/src/main/java/net/sf/jabref/pdfimport/PdfImporter.java index 1aad683d64dd..51b3eb4966ae 100644 --- a/src/main/java/net/sf/jabref/pdfimport/PdfImporter.java +++ b/src/main/java/net/sf/jabref/pdfimport/PdfImporter.java @@ -41,6 +41,7 @@ import net.sf.jabref.importer.fileformat.PdfContentImporter; import net.sf.jabref.importer.fileformat.PdfXmpImporter; import net.sf.jabref.logic.l10n.Localization; +import net.sf.jabref.logic.labelpattern.LabelPatternPreferences; import net.sf.jabref.logic.labelpattern.LabelPatternUtil; import net.sf.jabref.logic.util.UpdateField; import net.sf.jabref.logic.util.io.FileUtil; @@ -252,7 +253,7 @@ private void doContentImport(String fileName, List res) { panel.getDatabase().insertEntry(entry); panel.markBaseChanged(); LabelPatternUtil.makeLabel(panel.getBibDatabaseContext().getMetaData(), panel.getDatabase(), entry, - Globals.prefs); + LabelPatternPreferences.fromPreferences(Globals.prefs)); DroppedFileHandler dfh = new DroppedFileHandler(frame, panel); dfh.linkPdfToEntry(fileName, entry); panel.highlightEntry(entry); diff --git a/src/test/java/net/sf/jabref/importer/CustomImporterTest.java b/src/test/java/net/sf/jabref/importer/CustomImporterTest.java index fac5fb75ab8f..c2a8a1a96118 100644 --- a/src/test/java/net/sf/jabref/importer/CustomImporterTest.java +++ b/src/test/java/net/sf/jabref/importer/CustomImporterTest.java @@ -97,7 +97,7 @@ public void testCompareToGreater() { @Test public void testCompareToEven() { - assertEquals(0, importer.compareTo(importer)); + assertEquals(0, importer.compareTo(new CustomImporter(new CopacImporter()))); } @Test diff --git a/src/test/java/net/sf/jabref/logic/labelpattern/LabelPatternUtilTest.java b/src/test/java/net/sf/jabref/logic/labelpattern/LabelPatternUtilTest.java index e372e9a09ffb..4faaa48f4ffc 100644 --- a/src/test/java/net/sf/jabref/logic/labelpattern/LabelPatternUtilTest.java +++ b/src/test/java/net/sf/jabref/logic/labelpattern/LabelPatternUtilTest.java @@ -50,20 +50,21 @@ public void setUp() { @Test public void testAndInAuthorName() { BibEntry entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Simon Holland}}"); - assertEquals("Holland", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth"))); + assertEquals("Holland", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth"), true)); } @Test public void testAndAuthorNames() { String bibtexString = "@ARTICLE{whatevery, author={Mari D. Herland and Mona-Iren Hauge and Ingeborg M. Helgeland}}"; BibEntry entry = BibtexParser.singleFromString(bibtexString); - assertEquals("HerlandHaugeHelgeland", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry, "authors3"))); + assertEquals("HerlandHaugeHelgeland", + LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry, "authors3"), true)); } @Test public void testSpecialLatexCharacterInAuthorName() { BibEntry entry = BibtexParser.singleFromString("@ARTICLE{kohn, author={Simon Popovi\\v{c}ov\\'{a}}}"); - assertEquals("Popovicova", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry, "auth"))); + assertEquals("Popovicova", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry, "auth"), true)); } /** @@ -73,40 +74,40 @@ public void testSpecialLatexCharacterInAuthorName() { @Test public void testMakeLabelAndCheckLegalKeys() { BibEntry entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Andreas Köning}, year={2000}}"); - assertEquals("Koen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"))); + assertEquals("Koen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"), true)); entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Andreas Áöning}, year={2000}}"); - assertEquals("Aoen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"))); + assertEquals("Aoen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"), true)); entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Andreas Éöning}, year={2000}}"); - assertEquals("Eoen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"))); + assertEquals("Eoen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"), true)); entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Andreas Íöning}, year={2000}}"); - assertEquals("Ioen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"))); + assertEquals("Ioen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"), true)); entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Andreas Ĺöning}, year={2000}}"); - assertEquals("Loen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"))); + assertEquals("Loen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"), true)); entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Andreas Ńöning}, year={2000}}"); - assertEquals("Noen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"))); + assertEquals("Noen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"), true)); entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Andreas Óöning}, year={2000}}"); - assertEquals("Ooen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"))); + assertEquals("Ooen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"), true)); entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Andreas Ŕöning}, year={2000}}"); - assertEquals("Roen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"))); + assertEquals("Roen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"), true)); entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Andreas Śöning}, year={2000}}"); - assertEquals("Soen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"))); + assertEquals("Soen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"), true)); entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Andreas Úöning}, year={2000}}"); - assertEquals("Uoen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"))); + assertEquals("Uoen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"), true)); entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Andreas Ýöning}, year={2000}}"); - assertEquals("Yoen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"))); + assertEquals("Yoen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"), true)); entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Andreas Źöning}, year={2000}}"); - assertEquals("Zoen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"))); + assertEquals("Zoen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"), true)); } /** @@ -115,19 +116,19 @@ public void testMakeLabelAndCheckLegalKeys() { @Test public void testMakeLabelAndCheckLegalKeysAccentGrave() { BibEntry entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Andreas Àöning}, year={2000}}"); - assertEquals("Aoen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"))); + assertEquals("Aoen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"), true)); entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Andreas Èöning}, year={2000}}"); - assertEquals("Eoen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"))); + assertEquals("Eoen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"), true)); entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Andreas Ìöning}, year={2000}}"); - assertEquals("Ioen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"))); + assertEquals("Ioen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"), true)); entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Andreas Òöning}, year={2000}}"); - assertEquals("Ooen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"))); + assertEquals("Ooen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"), true)); entry0 = BibtexParser.singleFromString("@ARTICLE{kohn, author={Andreas Ùöning}, year={2000}}"); - assertEquals("Uoen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"))); + assertEquals("Uoen", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry0, "auth3"), true)); } /** @@ -145,43 +146,43 @@ public void testCheckLegalKey() { //"Ł ł Ő ő Ű ű Ŀ ŀ Ħ ħ Ð ð Þ þ Œ œ Æ æ Ø ø Å å Ə ə String accents = "ÀàÈèÌìÒòÙù  â Ĉ ĉ Ê ê Ĝ ĝ Ĥ ĥ Î î Ĵ ĵ Ô ô Ŝ ŝ Û û Ŵ ŵ Ŷ ŷ"; String expectedResult = "AaEeIiOoUuAaCcEeGgHhIiJjOoSsUuWwYy"; - assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents)); + assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents, true)); accents = "ÄäËëÏïÖöÜüŸÿ"; expectedResult = "AeaeEeIiOeoeUeueYy"; - assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents)); + assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents, true)); accents = "Ç ç Ģ ģ Ķ ķ Ļ ļ Ņ ņ Ŗ ŗ Ş ş Ţ ţ"; expectedResult = "CcGgKkLlNnRrSsTt"; - assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents)); + assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents, true)); accents = "Ă ă Ĕ ĕ Ğ ğ Ĭ ĭ Ŏ ŏ Ŭ ŭ"; expectedResult = "AaEeGgIiOoUu"; - assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents)); + assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents, true)); accents = "Ċ ċ Ė ė Ġ ġ İ ı Ż ż"; expectedResult = "CcEeGgIiZz"; - assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents)); + assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents, true)); accents = "Ą ą Ę ę Į į Ǫ ǫ Ų ų"; expectedResult = "AaEeIiOoUu"; // O or Q? o or q? - assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents)); + assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents, true)); accents = "Ā ā Ē ē Ī ī Ō ō Ū ū Ȳ ȳ"; expectedResult = "AaEeIiOoUuYy"; - assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents)); + assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents, true)); accents = "Ǎ ǎ Č č Ď ď Ě ě Ǐ ǐ Ľ ľ Ň ň Ǒ ǒ Ř ř Š š Ť ť Ǔ ǔ Ž ž"; expectedResult = "AaCcDdEeIiLlNnOoRrSsTtUuZz"; - assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents)); + assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents, true)); expectedResult = "AaEeIiNnOoUuYy"; accents = "ÃãẼẽĨĩÑñÕõŨũỸỹ"; - assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents)); + assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents, true)); accents = "Ḍ ḍ Ḥ ḥ Ḷ ḷ Ḹ ḹ Ṃ ṃ Ṇ ṇ Ṛ ṛ Ṝ ṝ Ṣ ṣ Ṭ ṭ"; expectedResult = "DdHhLlLlMmNnRrRrSsTt"; - assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents)); + assertEquals(expectedResult, LabelPatternUtil.checkLegalKey(accents, true)); String totest = "À à È è Ì ì Ò ò Ù ù  â Ĉ ĉ Ê ê Ĝ ĝ Ĥ ĥ Î î Ĵ ĵ Ô ô Ŝ ŝ Û û Ŵ ŵ Ŷ ŷ Ä ä Ë ë Ï ï Ö ö Ü ü Ÿ ÿ " + "à ã Ẽ ẽ Ĩ ĩ Ñ ñ Õ õ Ũ ũ Ỹ ỹ Ç ç Ģ ģ Ķ ķ Ļ ļ Ņ ņ Ŗ ŗ Ş ş Ţ ţ" @@ -195,7 +196,7 @@ public void testCheckLegalKey() { "AaEeGgIiOoUu" + "CcEeGgIiZzAaEeIiOoUu" + "DdHhLlLlMmNnRrRrSsTt"; - assertEquals(expectedResults, LabelPatternUtil.checkLegalKey(totest)); + assertEquals(expectedResults, LabelPatternUtil.checkLegalKey(totest, true)); } @Test @@ -221,7 +222,7 @@ public void testFirstAuthorNull() { @Test public void testUniversity() { BibEntry entry = BibtexParser.singleFromString("@ARTICLE{kohn, author={{Link{\\\"{o}}ping University}}}"); - assertEquals("UniLinkoeping", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry, "auth"))); + assertEquals("UniLinkoeping", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry, "auth"), true)); } @Test @@ -229,21 +230,23 @@ public void testDepartment() { BibEntry entry = BibtexParser .singleFromString( "@ARTICLE{kohn, author={{Link{\\\"{o}}ping University, Department of Electrical Engineering}}}"); - assertEquals("UniLinkoepingEE", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry, "auth"))); + assertEquals("UniLinkoepingEE", + LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry, "auth"), true)); } @Test public void testSchool() { BibEntry entry = BibtexParser.singleFromString( "@ARTICLE{kohn, author={{Link{\\\"{o}}ping University, School of Computer Engineering}}}"); - assertEquals("UniLinkoepingCE", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry, "auth"))); + assertEquals("UniLinkoepingCE", + LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry, "auth"), true)); } @Test public void testInstituteOfTechnology() { BibEntry entry = BibtexParser .singleFromString("@ARTICLE{kohn, author={{Massachusetts Institute of Technology}}}"); - assertEquals("MIT", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry, "auth"))); + assertEquals("MIT", LabelPatternUtil.checkLegalKey(LabelPatternUtil.makeLabel(entry, "auth"), true)); } @Test @@ -714,13 +717,14 @@ public void testCheckLegalKey2() { assertEquals("", LabelPatternUtil.checkLegalKey("\n\t\r", false)); // Check null input - assertNull(LabelPatternUtil.checkLegalKey(null)); assertNull(LabelPatternUtil.checkLegalKey(null, true)); assertNull(LabelPatternUtil.checkLegalKey(null, false)); // Use preferences setting - assertEquals("AAAA", LabelPatternUtil.checkLegalKey("AA AA")); - assertEquals("", LabelPatternUtil.checkLegalKey("\n\t\r")); + assertEquals("AAAA", LabelPatternUtil.checkLegalKey("AA AA", + Globals.prefs.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY))); + assertEquals("", LabelPatternUtil.checkLegalKey("\n\t\r", + Globals.prefs.getBoolean(JabRefPreferences.ENFORCE_LEGAL_BIBTEX_KEY))); } @Test diff --git a/src/test/java/net/sf/jabref/logic/layout/LayoutTest.java b/src/test/java/net/sf/jabref/logic/layout/LayoutTest.java index 5d5e8cdf1962..8a6705af398d 100644 --- a/src/test/java/net/sf/jabref/logic/layout/LayoutTest.java +++ b/src/test/java/net/sf/jabref/logic/layout/LayoutTest.java @@ -38,8 +38,8 @@ public String t1BibtexString() { + " title = {Effective work practices for floss development: A model and propositions},\n" + " booktitle = {Hawaii International Conference On System Sciences (HICSS)},\n" + " year = {2005},\n" + " owner = {oezbek},\n" + " timestamp = {2006.05.29},\n" - + " url = {http://james.howison.name/publications.html},\n" + " abstract = {\\~{n}\n" + "\\~n\n" - + "\\'i\n" + "\\i\n" + "\\i}\n" + "}\n"; + + " url = {http://james.howison.name/publications.html},\n" + " abstract = {\\~{n} \\~n " + + "\\'i \\i \\i}\n" + "}\n"; } public static BibEntry bibtexString2BibtexEntry(String s) throws IOException { @@ -68,7 +68,6 @@ public void testLayoutBibtextype() throws IOException { } @Test - @Ignore public void testHTMLChar() throws IOException { String layoutText = layout("\\begin{author}\\format[HTMLChars]{\\author}\\end{author} ", "@other{bla, author={This\nis\na\ntext}}"); @@ -79,8 +78,12 @@ public void testHTMLChar() throws IOException { "@other{bla, author={This\nis\na\ntext}}"); Assert.assertEquals("This is a text", layoutText); + } - layoutText = layout("\\begin{author}\\format[HTMLChars]{\\author}\\end{author} ", + @Test + @Ignore + public void testHTMLCharDoubleLineBreak() throws IOException { + String layoutText = layout("\\begin{author}\\format[HTMLChars]{\\author}\\end{author} ", "@other{bla, author={This\nis\na\n\ntext}}"); Assert.assertEquals("This is a
text ", layoutText); @@ -100,7 +103,6 @@ public void testPluginLoading() throws IOException { * @throws Exception */ @Test - @Ignore public void testLayout() throws IOException { String layoutText = layout( @@ -108,7 +110,7 @@ public void testLayout() throws IOException { t1BibtexString()); Assert.assertEquals( - "

Abstract: ñ ñ í ı ı
", + "

Abstract: ñ ñ í ı ı
", layoutText); } } diff --git a/src/test/java/net/sf/jabref/logic/net/CookieTest.java b/src/test/java/net/sf/jabref/logic/net/CookieTest.java index c1f23cbfb8b5..81d4747b722b 100644 --- a/src/test/java/net/sf/jabref/logic/net/CookieTest.java +++ b/src/test/java/net/sf/jabref/logic/net/CookieTest.java @@ -5,36 +5,99 @@ import org.junit.Test; +import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; public class CookieTest { + @Test(expected = IllegalArgumentException.class) + public void testIncorrectExpiresFormat() throws URISyntaxException { + Cookie cookie = new Cookie(new URI("http://jabref.org/"), + "name=TestCookie; expires=Tue, 25/07/10 16:43:15 GMT"); + fail(); + } + + @Test(expected = IllegalArgumentException.class) + public void testIncorrectDomain() throws URISyntaxException { + Cookie cookie = new Cookie(new URI("http://jabref.org/"), + "name=TestCookie; domain=google.com"); + fail(); + } @Test - public void testCookieHyphenFormat() throws URISyntaxException { - Cookie cookie = new Cookie(new URI("hhh"), "name=TestCookie; expires=Tue, 25-Jul-2017 16:43:15 GMT"); + public void testHasExpiredFalse() throws URISyntaxException { + Cookie cookie = new Cookie(new URI("http://jabref.org/"), + "name=TestCookie; expires=Tue, 25-Jul-45 16:43:15 GMT"); + assertFalse(cookie.hasExpired()); } + @Test - public void testCookieHyphenTwoDigitYearFormat() throws URISyntaxException { - Cookie cookie = new Cookie(new URI("hhh"), "name=TestCookie; expires=Tue, 25-Jul-17 16:43:15 GMT"); + public void testHasExpiredFalseWhenNotSet() throws URISyntaxException { + Cookie cookie = new Cookie(new URI("http://jabref.org/"), "name=TestCookie; domain=jabref.org; path=/"); + assertFalse(cookie.hasExpired()); } @Test - public void testCookieSpaceFormat() throws URISyntaxException { - Cookie cookie = new Cookie(new URI("hhh"), "name=TestCookie; expires=Tue, 25 Jul 2017 16:43:15 GMT"); + public void testHasExpiredTrueSpaceFormat() throws URISyntaxException { + Cookie cookie = new Cookie(new URI("http://jabref.org/"), + "name=Nicholas; expires=Sat, 02 May 2009 23:38:25 GMT"); + assertTrue(cookie.hasExpired()); } @Test - public void testHasExpiredFalse() throws URISyntaxException { - Cookie cookie = new Cookie(new URI("hhh"), "name=TestCookie; expires=Tue, 25-Jul-45 16:43:15 GMT"); - assertFalse(cookie.hasExpired()); + public void testHasExpiredTrueHyphenFormat() throws URISyntaxException { + Cookie cookie = new Cookie(new URI("http://jabref.org/"), + "name=Nicholas; expires=Sat, 02-May-2009 23:38:25 GMT"); + assertTrue(cookie.hasExpired()); } @Test - public void testHasExpiredTrue() throws URISyntaxException { - Cookie cookie = new Cookie(new URI("hhh"), "name=Nicholas; expires=Sat, 02 May 2009 23:38:25 GMT"); + public void testHasExpiredTrueTwoDigitYearHyphenFormat() throws URISyntaxException { + Cookie cookie = new Cookie(new URI("http://jabref.org/"), "name=Nicholas; expires=Sat, 02-May-09 23:38:25 GMT"); assertTrue(cookie.hasExpired()); } + + @Test + public void testMatches() throws URISyntaxException { + Cookie cookie = new Cookie(new URI("http://jabref.org/"), + "LSID=LSDLSD; Domain=jabref.org; Path=/; Secure; expires=Sat, 02-May-99 23:38:25 GMT"); + assertTrue(cookie.matches(new URI("http://jabref.org/"))); + } + + @Test + public void testMatchesWWWInDomain() throws URISyntaxException { + Cookie cookie = new Cookie(new URI("http://www.jabref.org/"), + "LSID=LSDLSD; Domain=www.jabref.org; Path=/; Secure; expires=Sat, 02-May-99 23:38:25 GMT"); + assertTrue(cookie.matches(new URI("http://jabref.org/"))); + } + + @Test + public void testMatchesDotInDomain() throws URISyntaxException { + Cookie cookie = new Cookie(new URI("http://jabref.org/"), + "LSID=LSDLSD; Domain=.jabref.org; Path=/; Secure; expires=Sat, 02-May-99 23:38:25 GMT"); + assertTrue(cookie.matches(new URI("http://jabref.org/"))); + } + + @Test + public void testNotMatchesWhenExpired() throws URISyntaxException { + Cookie cookie = new Cookie(new URI("http://jabref.org/"), + "LSID=LSDLSD; Domain=jabref.org; Path=/; Secure; expires=Sat, 02-May-09 23:38:25 GMT"); + assertFalse(cookie.matches(new URI("http://jabref.org/"))); + } + + @Test + public void testNotMatchesWrongPath() throws URISyntaxException { + Cookie cookie = new Cookie(new URI("http://jabref.org/"), + "LSID=LSDLSD; Domain=jabref.org; Path=/blog/; Secure; expires=Sat, 02-May-99 23:38:25 GMT"); + assertFalse(cookie.matches(new URI("http://jabref.org/"))); + } + + @Test + public void testToString() throws URISyntaxException { + Cookie cookie = new Cookie(new URI("http://jabref.org/"), "LSID=LSDLSD; Domain=jabref.org; Path=/; Secure"); + assertEquals("LSID=LSDLSD", cookie.toString()); + } } diff --git a/src/test/java/net/sf/jabref/logic/util/strings/StringUtilTest.java b/src/test/java/net/sf/jabref/logic/util/strings/StringUtilTest.java index 85dc3faa6271..20ad854e4eb8 100644 --- a/src/test/java/net/sf/jabref/logic/util/strings/StringUtilTest.java +++ b/src/test/java/net/sf/jabref/logic/util/strings/StringUtilTest.java @@ -11,6 +11,7 @@ import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; public class StringUtilTest { @@ -243,6 +244,38 @@ public void testIntValueOfExceptionfIfStringEmpty() { StringUtil.intValueOf(""); } + @Test + public void testIntValueOfWithNullSingleDigit() { + assertEquals(Integer.valueOf(1), StringUtil.intValueOfWithNull("1")); + assertEquals(Integer.valueOf(2), StringUtil.intValueOfWithNull("2")); + assertEquals(Integer.valueOf(8), StringUtil.intValueOfWithNull("8")); + } + + @Test + public void testIntValueOfWithNullLongString() { + assertEquals(Integer.valueOf(1234567890), StringUtil.intValueOfWithNull("1234567890")); + } + + @Test + public void testIntValueOfWithNullStartWithZeros() { + assertEquals(Integer.valueOf(1234), StringUtil.intValueOfWithNull("001234")); + } + + @Test + public void testIntValueOfWithNullExceptionIfStringContainsLetter() { + assertNull(StringUtil.intValueOfWithNull("12A2")); + } + + @Test + public void testIntValueOfWithNullExceptionIfStringNull() { + assertNull(StringUtil.intValueOfWithNull(null)); + } + + @Test + public void testIntValueOfWithNullExceptionfIfStringEmpty() { + assertNull(StringUtil.intValueOfWithNull("")); + } + @Test public void testQuoteSimple() { assertEquals("a::", StringUtil.quote("a:", "", ':'));