package org.docear.plugin.bibtex.dialogs; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; import java.awt.Font; import java.awt.Window; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.WindowEvent; import java.io.IOException; import java.io.StringReader; import java.net.URI; import java.util.Calendar; import java.util.Collection; import java.util.Iterator; import java.util.Locale; import javax.swing.DefaultListCellRenderer; import javax.swing.DefaultListModel; import javax.swing.ImageIcon; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.ListSelectionModel; import javax.swing.SwingUtilities; import javax.swing.border.BevelBorder; import javax.swing.border.CompoundBorder; import javax.swing.border.EmptyBorder; import javax.swing.border.MatteBorder; import javax.swing.border.SoftBevelBorder; import javax.ws.rs.core.MultivaluedMap; import net.sf.jabref.BibtexEntry; import net.sf.jabref.Globals; import net.sf.jabref.export.ExportFormats; import net.sf.jabref.export.layout.LayoutHelper; import net.sf.jabref.imports.BibtexParser; import org.docear.plugin.bibtex.ReferencesController; import org.docear.plugin.bibtex.jabref.JabRefCommons; import org.docear.plugin.bibtex.jabref.JabRefCommons.MetadataCallableResult; import org.docear.plugin.core.ui.MultiLineActionLabel; import org.docear.plugin.core.ui.wizard.Wizard; import org.docear.plugin.core.ui.wizard.WizardSession; import org.docear.plugin.core.ui.wizard.WizardPageDescriptor; import org.docear.plugin.services.ServiceController; import org.docear.plugin.services.features.io.DocearServiceResponse.Status; import org.docear.plugin.services.features.user.DocearUserController; import org.docear.plugin.services.features.user.action.DocearUserRegistrationAction; import org.freeplane.core.ui.components.UITools; import org.freeplane.core.util.TextUtils; import org.freeplane.features.mode.Controller; import com.jgoodies.forms.factories.FormFactory; import com.jgoodies.forms.layout.ColumnSpec; import com.jgoodies.forms.layout.FormLayout; import com.jgoodies.forms.layout.RowSpec; public class PdfMetadataListDialog extends JPanel { private static final long serialVersionUID = -627410651667772600L; private JList list; private BibtexEntryListModel listModel; private Collection<BibtexEntry> entries; private boolean requesting; private boolean remoteBib; private boolean hasError; private JScrollPane scrollPane; private boolean bibResults; private JLabel lblNewLabel; public PdfMetadataListDialog() { setPreferredSize(new Dimension(640, 200)); setLayout(new FormLayout(new ColumnSpec[] { ColumnSpec.decode("434px:grow"),}, new RowSpec[] { RowSpec.decode("max(30dlu;default)"), RowSpec.decode("fill:151px:grow"),})); JPanel panel = new JPanel(); panel.setBackground(Color.WHITE); add(panel, "1, 1, fill, fill"); panel.setLayout(new FormLayout(new ColumnSpec[] { FormFactory.RELATED_GAP_COLSPEC, ColumnSpec.decode("default:grow"), FormFactory.RELATED_GAP_COLSPEC,}, new RowSpec[] { RowSpec.decode("max(20dlu;default)"), RowSpec.decode("default:grow"),})); lblNewLabel = new JLabel(TextUtils.getText("docear.metadata.import.help")); panel.add(lblNewLabel, "2, 1"); Calendar cal = Calendar.getInstance(Locale.GERMANY); cal.clear(); cal.set(2014, 2, 15); if(cal.after(Calendar.getInstance(Locale.GERMANY))) { MultiLineActionLabel message = new MultiLineActionLabel("<b style=\"color: red;\">Do you want better PDF metadata extraction and automatic PDF file renaming? </b><action cmd=\"donate\">Read here...</action>"); message.setPreferredSize(new Dimension(0, 25)); message.setFont(message.getFont().deriveFont(Font.BOLD)); message.setBackground(panel.getBackground()); message.addActionListener(new ActionListener() { @Override public void actionPerformed(ActionEvent event) { try { Controller.getCurrentController().getViewController().openDocument(URI.create("http://www.docear.org/2014/01/23/call-for-donation-automatic-pdf-metadata-extraction-and-renaming/")); } catch (IOException ignore) { } } }); panel.add(message, "1, 2, 3, 1, fill, fill"); } scrollPane = new JScrollPane(); scrollPane.setViewportBorder(new SoftBevelBorder(BevelBorder.LOWERED, null, null, null, null)); add(scrollPane, "1, 2, fill, fill"); JLabel lblWaiting = new JLabel(new ImageIcon(this.getClass().getResource("/ajax-loader.gif")), JLabel.CENTER); lblWaiting.setBackground(Color.WHITE); scrollPane.setViewportView(lblWaiting); } public BibtexEntry getSelectedEntry() { if(list.getSelectedIndex() > -1) { return listModel.getEntry(list.getSelectedIndex()); } return null; } private void updateResults() { if(entries != null && !bibResults) { bibResults = true; listModel = new BibtexEntryListModel(); list = new JList(listModel); list.setSelectedIndex(0); list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); list.setCellRenderer(new DefaultListCellRenderer() { private static final long serialVersionUID = 4805846114365117400L; public Component getListCellRendererComponent(JList table, Object value, int index, final boolean isSelected, boolean hasFocus) { StringBuilder sb = new StringBuilder(); sb.append("<html><body>"); sb.append(value); sb.append("</body></html>"); final JLabel label = (JLabel) super.getListCellRendererComponent(table, sb, index, isSelected, hasFocus); if(index > 0) { label.setBorder(new CompoundBorder(new MatteBorder(2, 0, 0, 0, (Color) new Color(0, 0, 0)), new EmptyBorder(10, 8, 10, 8))); } else { label.setBorder(new EmptyBorder(10, 8, 10, 8)); } return label; } }); scrollPane.setViewportView(list); listModel.fireDataChanged(); if(!hasRemoteBib()) { lblNewLabel.setText(TextUtils.getText("docear.metadata.import.help.fallback")); } } } public void runServiceRequest(final String hash, final MultivaluedMap<String, String> params) { if(!requesting) { requesting = true; new Thread() { public void run() { remoteBib = true; try { MetadataCallableResult ret = JabRefCommons.requestBibTeX(hash, params); if (ret.hasError()) { hasError = true; //Replace with local presentation if(ServiceController.getCurrentUser() == DocearUserController.LOCAL_USER) { showErrorMessage(ret.getError(), ret.getStatus() == Status.UNAUTHORIZED); } } String bib = ret.getResult(); // if no bibtex found -> create misc entry with title only if (bib == null) { remoteBib = false; StringBuilder sb = new StringBuilder(); sb.append("@ARTICLE{,\n title = {"); sb.append(params.get("title").get(0)); sb.append("}\n}"); bib = sb.toString(); } entries = BibtexParser.fromString(bib); SwingUtilities.invokeLater(new Runnable() { public void run() { updateResults(); } }); } catch (Exception e) { hasError = true; } } }.start(); } } private void showErrorMessage(String message, boolean showRegistration) { Window window = SwingUtilities.getWindowAncestor(PdfMetadataListDialog.this); if(window != null && window != UITools.getFrame()) { PdfMetadataListDialog.this.dispatchEvent(new WindowEvent(window, WindowEvent.WINDOW_CLOSING)); window.setVisible(false); } final Wizard wizard = new Wizard(UITools.getFrame()); final Object regId = DocearUserRegistrationAction.addRegistrationPages(wizard); MetadataErrorPage page = new MetadataErrorPage(message, showRegistration); //JOptionPane.showMessageDialog(UITools.getFrame(), message , , JOptionPane.ERROR_MESSAGE); WizardPageDescriptor desc = new WizardPageDescriptor("error_message", page) { @Override public WizardPageDescriptor getNextPageDescriptor(WizardSession context) { wizard.cancel(); return null; } @Override public WizardPageDescriptor getBackPageDescriptor(WizardSession context) { return context.getModel().getPage(regId); } }; wizard.registerWizardPanel(desc); wizard.setStartPage(desc.getIdentifier()); new Thread(new Runnable() { public void run() { int ret = wizard.show(); if(ret == Wizard.OK_OPTION) { DocearUserRegistrationAction.useRegisteredUser(wizard); } } }).start(); } class BibtexEntryListModel extends DefaultListModel { private static final long serialVersionUID = 2610007578887026651L; public BibtexEntryListModel() { } public void fireDataChanged() { fireContentsChanged(this, 0, entries.size()-1); } public BibtexEntry getEntry(int rowIndex) { if(rowIndex < 0 || rowIndex >= entries.size()) { throw new IndexOutOfBoundsException(); } int i=0; for (Iterator<BibtexEntry> iterator = entries.iterator(); iterator.hasNext(); i++) { if(i==rowIndex) { return iterator.next(); } iterator.next(); } return null; } public boolean isCellEditable(int row, int column) { return false; } public int getSize() { if(entries == null) { return 0; } return entries.size(); } public Object getElementAt(int index) { BibtexEntry entry = getEntry(index); if(entry == null) { return null; } StringBuffer sb = new StringBuffer(); StringReader sr = new StringReader(Globals.prefs.get("preview0").replaceAll("__NEWLINE__", "\n")); ExportFormats.entryNumber = 1; // Set entry number in case that is included in the preview layout. try { sb.append(new LayoutHelper(sr).getLayoutFromText(Globals.FORMATTER_PACKAGE).doLayout(entry,ReferencesController.getController().getJabrefWrapper().getDatabase())); } catch (Exception e) { } return sb.toString(); } } public Collection<BibtexEntry> getEntries() { return this.entries; } public boolean hasRemoteBib() { return remoteBib; } public boolean wasSuccessful() { return !hasError; } }