Save This Page
Home » openjdk-7 » net » sf » bibkeeper » [javadoc | source]
    1   package net.sf.bibkeeper;
    2   
    3   import javax.swing;
    4   import javax.swing.event;
    5   import javax.swing.text.JTextComponent;
    6   import java.awt;
    7   import java.util;
    8   import java.awt.event;
    9   import java.awt.datatransfer;
   10   import java.io.StringWriter;
   11   import java.io.IOException;
   12   import net.sf.bibkeeper.undo.UndoableFieldChange;
   13   import net.sf.bibkeeper.undo.UndoableInsertEntry;
   14   import net.sf.bibkeeper.undo.UndoableRemoveEntry;
   15   import net.sf.bibkeeper.undo.NamedCompound;
   16   import net.sf.bibkeeper.export.LatexFieldFormatter;
   17   import java.beans;
   18   
   19   public class EntryTypeForm extends JDialog implements VetoableChangeListener {
   20   
   21       /* 
   22        * GUI component that allows editing of the fields of a BibtexEntry.
   23        * EntryTypeForm also registers itself as a VetoableChangeListener,
   24        * receiving events whenever a field of the entry changes, enabling the
   25        * text fields to update themselves if the change is made from somewhere
   26        * else.
   27        */
   28   
   29       // A reference to the entry this object works on.
   30       BibtexEntry entry;
   31   
   32       CloseAction closeAction; 
   33       // The action concerned with closing the window.
   34   
   35       CopyKeyAction copyKeyAction;
   36       // The action concerned with copying the BibTeX key to the clipboard.
   37   
   38       StoreFieldAction storeFieldAction;
   39       // The action concerned with storing a field value.
   40   
   41   
   42       SwitchLeftAction switchLeftAction = new SwitchLeftAction();
   43       SwitchRightAction switchRightAction = new SwitchRightAction();
   44       // The actions concerned with switching the panels.
   45   
   46       GenerateKeyAction generateKeyAction ;
   47       // The action which generates a bibtexkey for this entry. 
   48   
   49       Container contentPane = getContentPane();
   50       JPanel mainPanel = new JPanel(), // The area below the toolbar.
   51   	srcPanel = new JPanel();
   52       FieldPanel reqPanel = new FieldPanel(),
   53   	optPanel = new FieldPanel(),
   54   	genPanel = new FieldPanel();
   55       JTextField bibtexKey;
   56       JTextArea source;
   57       JTabbedPane tabbed = new JTabbedPane();
   58       GridBagLayout gbl = new GridBagLayout();
   59       GridBagConstraints con = new GridBagConstraints();
   60       JLabel lab;
   61       BibtexBaseFrame baseFrame; // The BibtexBaseFrame this dialog belongs to.
   62   
   63   
   64       boolean updateSource = true; // This can be set to false to stop the source
   65       // text area from gettin updated. This is used in cases where the source
   66       // couldn't be parsed, and the user is given the option to edit it.
   67       boolean lastSourceAccepted = true; // This indicates whether the last attempt
   68       // at parsing the source was successful. It is used to determine whether the
   69       // dialog should close; it should stay open if the user received an error
   70       // message about the source, whatever he or she chose to do about it.
   71       String lastSourceStringAccepted = null; // This is used to prevent double
   72       // updates after editing source.
   73       double optW = 0, reqW = 1, genW = 0; // Variables for total weight of fields.
   74       // These values can be used to calculate the preferred height for the form.
   75       // reqW starts at 1 because it needs room for the bibtex key field.
   76   
   77       private final int REQ=0, OPT=1, GEN=2, FIELD_WIDTH=40, FIELD_HEIGHT=2;
   78       private final String KEY_PROPERTY = "bibtexkey";
   79       BibkeeperPrefs prefs;
   80       HelpAction helpAction;
   81   
   82       public EntryTypeForm(BibtexBaseFrame baseFrame_, BibtexEntry entry_, BibkeeperPrefs prefs_) {
   83   	super(baseFrame_);
   84   	baseFrame = baseFrame_;
   85   	entry = entry_;
   86   	prefs = prefs_;
   87   
   88   	entry.addPropertyChangeListener(this);
   89   
   90   	setTitle(entry.getType().getName());
   91   	setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
   92   	helpAction = new HelpAction
   93   	    (baseFrame.helpDiag, GUIGlobals.entryEditorHelp, "Help (F1)");
   94   	closeAction = new CloseAction();
   95   	copyKeyAction = new CopyKeyAction();
   96   //    generateKeyAction = new GenerateKeyAction(baseFrame,entry);
   97       generateKeyAction = new GenerateKeyAction(baseFrame);
   98   	storeFieldAction = new StoreFieldAction(this);
   99   	addWindowListener(new WindowAdapter() {
  100   		public void windowClosing(WindowEvent e) {
  101   		    closeAction.actionPerformed(null);
  102   		}	
  103   		public void windowOpened(WindowEvent e) {
  104   		    switch (tabbed.getSelectedIndex()) {
  105   		    case 0:
  106   			reqPanel.activate();
  107   			break;
  108   		    case 1:
  109   			optPanel.activate();
  110   			break;
  111   		    case 2:
  112   			genPanel.activate();
  113   			break;
  114   		    case 3:
  115   			source.requestFocus();
  116   			break;
  117   		    }
  118   		}	       
  119   	    });
  120   
  121   
  122   	contentPane.setLayout(new BorderLayout());
  123   	setupToolBar();
  124   	setupFieldPanels(reqPanel, optPanel, genPanel);
  125   	setupSourcePanel();
  126   	tabbed.setTabPlacement(SwingConstants.TOP);
  127   	tabbed.addTab("Required fields", new ImageIcon(GUIGlobals.showReqIconFile),
  128   		      reqPanel.getPane(), "Show required fields");
  129   	tabbed.addTab("Optional fields", new ImageIcon(GUIGlobals.showOptIconFile),
  130   		      optPanel.getPane(), "Show optional fields");
  131   	tabbed.addTab("General fields", new ImageIcon(GUIGlobals.showGenIconFile), 
  132   		      genPanel.getPane(), "Show general fields");
  133   	tabbed.addTab("Bibtex source", new ImageIcon(GUIGlobals.sourceIconFile), 
  134   		      srcPanel, "Show/edit bibtex source");
  135   	tabbed.addChangeListener(new TabListener());
  136   
  137   	contentPane.add(tabbed, BorderLayout.CENTER);
  138   
  139   	// We replace the default FocusTraversalPolicy with a subclass
  140   	// that only allows FieldEditor components to gain keyboard focus.	
  141   	setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
  142   		protected boolean accept(Component c) {
  143   		    return (super.accept(c) && (c instanceof JTextComponent));
  144   		}
  145   	    });
  146   
  147   	//Util.pr("opt: "+optW+"  req:"+reqW);
  148   	int prefHeight = (int)(Math.max(genW, Math.max(optW, reqW))*GUIGlobals.FORM_HEIGHT[prefs.getInt("entryTypeFormHeightFactor")]);
  149   	setSize(GUIGlobals.FORM_WIDTH[prefs.getInt("entryTypeFormWidth")], prefHeight);
  150   	if (prefs.getBoolean("defaultShowSource")) {
  151   	    tabbed.setSelectedIndex(3);
  152   	}
  153   	setResizable(true);
  154       }
  155   
  156       private void setupToolBar() {
  157   	JToolBar tlb = new JToolBar();
  158   
  159   	// The toolbar carries all the key bindings that are valid for the whole
  160   	// window.
  161   	ActionMap am = tlb.getActionMap();
  162   	InputMap im = tlb.getInputMap(JComponent.WHEN_IN_FOCUSED_WINDOW);
  163   	
  164   	im.put(GUIGlobals.exitDialog, "close");
  165   	am.put("close", closeAction);
  166   	im.put(KeyStroke.getKeyStroke(GUIGlobals.storeFieldKey), "store");
  167   	am.put("copyKey", copyKeyAction);
  168   	im.put(GUIGlobals.generateKeyStroke, "generateKey");
  169   	am.put("generateKey", generateKeyAction);
  170   	im.put(GUIGlobals.switchPanelLeft, "left");
  171   	am.put("left", switchLeftAction);
  172   	im.put(GUIGlobals.switchPanelRight, "right");
  173   	am.put("right", switchRightAction);
  174   	im.put(GUIGlobals.undoStroke, "undo");
  175   	am.put("undo", undoAction);
  176   	im.put(GUIGlobals.redoStroke, "redo");
  177   	am.put("redo", redoAction);
  178   	im.put(GUIGlobals.helpKeyStroke, "help");
  179   	am.put("help", helpAction);
  180   
  181   	tlb.setFloatable(false);
  182   	//tlb.add(closeAction);
  183   	//tlb.addSeparator();
  184   	tlb.add(copyKeyAction);
  185   	tlb.add(generateKeyAction);
  186   	tlb.addSeparator();
  187   	//tlb.add(undoAction);
  188   	//tlb.add(redoAction);
  189   	//tlb.addSeparator();
  190   	tlb.add(helpAction);
  191   	contentPane.add(tlb, BorderLayout.NORTH);
  192       }
  193   
  194       private void setupFieldPanels(FieldPanel req, FieldPanel opt, FieldPanel gen) {
  195   
  196   	// First we ask the BibtexEntry which fields are optional and
  197   	// required.
  198   	String[] reqFields = entry.getRequiredFields(),
  199   	    optFields = entry.getOptionalFields(),
  200   //        genFields = new String[] {"crossref", "url", "abstract", "comment"}; // May change...
  201   	    genFields = entry.getGeneralFields() ; 
  202   	
  203   	int iter, rmax, omax, gmax;
  204   	
  205   	gmax = genFields.length;
  206   	
  207   	if (reqFields == null) {
  208   	    iter = optFields.length;
  209   	    rmax = 0;
  210   	    omax = optFields.length;
  211   	} else if (optFields == null) {
  212   	    iter = reqFields.length;
  213   	    rmax = reqFields.length;
  214   	    omax = 0;
  215   	} else {
  216   	    iter = Math.max(reqFields.length, optFields.length);
  217   	    rmax = reqFields.length;
  218   	    omax = optFields.length;
  219   	}
  220   	FieldTextArea ta1 = null, ta2 = null, ta3 = null, firstR = null, firstO = null;
  221   	String stringContent;
  222   	Object content;
  223   
  224   	req.setLayout(gbl);
  225   	opt.setLayout(gbl);
  226   	gen.setLayout(gbl);
  227   	con.insets = new Insets(10,5,0,5);
  228   	//con.fill = GridBagConstraints.HORIZONTAL;
  229   
  230   	con.anchor = GridBagConstraints.WEST;
  231   
  232   	for (int i=0; i<iter; i++) {
  233   
  234   	    // Constraints for the labels.
  235   	    con.gridwidth = 1;
  236   	    con.weightx = 0;
  237   	    con.weighty = 0;
  238   	    con.fill = GridBagConstraints.NONE;
  239   	    if (i<rmax) {
  240   		if ((content = entry.getField(reqFields[i])) != null) {
  241   		    stringContent = content.toString();
  242   		} else
  243   		    stringContent = null;
  244   	    		
  245   		ta1 = new FieldTextArea(reqFields[i], stringContent);
  246   
  247   		setupJTextComponent(ta1);
  248   		if (i==0) {
  249   		    firstR = ta1;
  250   		    req.setActive(ta1);
  251   		}
  252   	    }
  253   	    if (i<omax) {
  254   		if ((content = entry.getField(optFields[i])) != null) {
  255   		    stringContent = content.toString();
  256   		} else
  257   		    stringContent = null;
  258   
  259   		ta2 = new FieldTextArea(optFields[i], stringContent);
  260   		setupJTextComponent(ta2);
  261   		if (i==0) { 
  262   		    firstO = ta2;
  263   		    opt.setActive(ta2);
  264   		}
  265   	    }
  266   	    if (i<gmax) {
  267   		if ((content = entry.getField(genFields[i])) != null) {
  268   		    stringContent = content.toString();
  269   		} else
  270   		    stringContent = null;
  271   
  272   		ta3 = new FieldTextArea(genFields[i], stringContent);
  273   		setupJTextComponent(ta3);
  274   		if (i==0) { 
  275   		    firstO = ta3;
  276   		    gen.setActive(ta3);
  277   		}
  278   	    }
  279   	    if (i<rmax) {
  280   		gbl.setConstraints(ta1.getLabel(),con);
  281   		req.add(ta1.getLabel());
  282   	    }
  283   	    if (i<omax) {
  284   		gbl.setConstraints(ta2.getLabel(),con);
  285   		opt.add(ta2.getLabel());
  286   	    }
  287   	    if (i<gmax) {
  288   		gbl.setConstraints(ta3.getLabel(),con);
  289   		gen.add(ta3.getLabel());
  290   	    }
  291   
  292   	    // Constraints for the text fields.
  293   	    con.gridwidth = GridBagConstraints.REMAINDER;
  294   	    con.weightx = 1;
  295   
  296   	    con.fill = GridBagConstraints.BOTH;
  297   	    if (i<rmax) {
  298   		con.weighty = GUIGlobals.getFieldWeight(reqFields[i]);
  299   		reqW += con.weighty;
  300   		//Util.pr(reqFields[i]+" "+con.weighty+"");
  301   		gbl.setConstraints(ta1.getPane(),con);
  302   		req.add(ta1.getPane());
  303   	    }
  304   	    if (i<omax) {
  305   		con.weighty = GUIGlobals.getFieldWeight(optFields[i]);
  306   		optW += con.weighty;
  307   		gbl.setConstraints(ta2.getPane(),con);
  308   		opt.add(ta2.getPane());
  309   	    }
  310   	    if (i<gmax) {
  311   		con.weighty = GUIGlobals.getFieldWeight(genFields[i]);
  312   		genW += con.weighty;
  313   		gbl.setConstraints(ta3.getPane(),con);
  314   		gen.add(ta3.getPane());
  315   	    }
  316   	}
  317   	// Add the edit field for Bibtex-key.
  318   	
  319   	con.insets.top += 25;
  320   	con.insets.bottom = 10;
  321   	con.gridwidth = 1;
  322   	con.weighty = 0;
  323   	con.weightx = 0;
  324   	con.anchor = GridBagConstraints.SOUTHWEST;
  325   	con.fill = GridBagConstraints.NONE;
  326   	FieldTextField tf = 
  327   	    new FieldTextField(KEY_PROPERTY,
  328   			       (String)entry.getField(KEY_PROPERTY));
  329   	gbl.setConstraints(tf.getLabel(),con);
  330   	req.add(tf.getLabel());
  331   	con.gridwidth = GridBagConstraints.REMAINDER;
  332   	//	con.anchor = GridBagConstraints.WEST;
  333   	con.weightx = 1;
  334   	con.fill = GridBagConstraints.HORIZONTAL;
  335   	setupJTextComponent(tf);
  336   	gbl.setConstraints(tf,con);
  337   	req.add(tf);
  338   
  339       }
  340   
  341       private void setupSourcePanel() {
  342   	source = new JTextArea();
  343   	con = new GridBagConstraints();
  344   	con.insets = new Insets(10,10,10,10);
  345   	con.fill = GridBagConstraints.BOTH;
  346   	con.gridwidth = GridBagConstraints.REMAINDER;
  347   	con.gridheight = GridBagConstraints.REMAINDER;
  348   	con.weightx = 1;
  349   	con.weighty = 1;
  350   	srcPanel.setLayout(gbl);
  351   	source.setEditable(prefs.getBoolean("enableSourceEditing"));
  352   	source.setLineWrap(true);
  353   	source.setTabSize(GUIGlobals.INDENT);
  354   	setupJTextComponent(source);
  355   	updateSource();
  356   
  357   
  358   	JScrollPane sp = new JScrollPane(source, 
  359   					 JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
  360   					 JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
  361   	gbl.setConstraints(sp, con);
  362   	srcPanel.add(sp);
  363   
  364       
  365       }
  366   
  367       private void updateSource() {
  368   	if (updateSource) {
  369   	    StringWriter sw = new StringWriter(200);
  370   	    try {
  371   		entry.write(sw, new net.sf.bibkeeper.export.LatexFieldFormatter());
  372   		String srcString = sw.getBuffer().toString();
  373   		source.setText(srcString);
  374   	    } catch (IOException ex) {
  375   		source.setText("Error: "+ex.getMessage()+"\n\n"
  376   			       +"Correct the entry, and "
  377   			       +"reopen editor to display/edit source.");
  378   		source.setEditable(false);
  379   	    }
  380   	}
  381       }
  382   
  383       private void setupJTextComponent(JTextComponent ta) {
  384   
  385   	// Activate autocompletion if it should be used for this field.
  386   	if ((ta instanceof FieldTextArea) && 
  387   	    (prefs.getBoolean("autoComplete"))) {
  388   	    FieldTextArea fta = (FieldTextArea)ta;
  389   	    Completer comp = baseFrame.getAutoCompleter(fta.getFieldName());
  390   	    if (comp != null)
  391   		fta.setAutoComplete(comp);
  392   	}
  393   
  394   	// Set up key bindings and focus listener for the FieldEditor.
  395   	InputMap im = ta.getInputMap(JComponent.WHEN_FOCUSED);
  396   	ActionMap am = ta.getActionMap();
  397   	//im.put(KeyStroke.getKeyStroke(GUIGlobals.closeKey), "close");
  398   	//am.put("close", closeAction);
  399   	im.put(KeyStroke.getKeyStroke(GUIGlobals.storeFieldKey), "store");
  400   	am.put("store", storeFieldAction);
  401   	im.put(GUIGlobals.switchPanelLeft, "left");
  402   	am.put("left", switchLeftAction);
  403   	im.put(GUIGlobals.switchPanelRight, "right");
  404   	am.put("right", switchRightAction);
  405   	im.put(GUIGlobals.helpKeyStroke, "help");
  406   	am.put("help", helpAction);
  407   	
  408   	try{
  409   	    int i = 0 ; 
  410   	    HashSet keys =  new HashSet(ta.getFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS)) ; 
  411   	    keys.add(AWTKeyStroke.getAWTKeyStroke("pressed TAB")) ; 
  412   	    ta.setFocusTraversalKeys(KeyboardFocusManager.FORWARD_TRAVERSAL_KEYS, keys) ; 
  413   	    keys = new HashSet(ta.getFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS)) ; 
  414   	    keys.add(KeyStroke.getKeyStroke("shift pressed TAB")) ; 
  415   	    ta.setFocusTraversalKeys(KeyboardFocusManager.BACKWARD_TRAVERSAL_KEYS, keys) ;
  416   	}catch(Throwable t){
  417   	    System.err.println(t) ; 
  418   	}
  419   	
  420   	
  421   	ta.addFocusListener(new FieldListener());
  422       }
  423   
  424       class FieldListener extends FocusAdapter {
  425   	/*
  426   	 * Focus listener that fires the storeFieldAction when a FieldTextArea
  427   	 * loses focus.
  428   	 */
  429   	public void focusGained(FocusEvent e) {
  430   	    //Util.pr("Gained focus "+e.getSource().toString().substring(0,30));
  431   	    if (e.getSource() instanceof FieldEditor) {
  432   		FieldEditor ta = (FieldEditor)e.getSource();
  433   		Component parent = ta.getParent();
  434   		while (!(parent instanceof FieldPanel)) {
  435   		    parent = parent.getParent();
  436   		}
  437   		((FieldPanel)parent).setActive(ta);
  438   	    } else {
  439   		// The source panel must have been chosen. Update it.
  440   		if (baseFrame.baseChanged)
  441   		    updateSource();
  442   	    }
  443   	}
  444   
  445   	public void focusLost(FocusEvent e) {	  
  446   	    //Util.pr("Lost focus "+e.getSource().toString().substring(0,30));
  447   	    if (!e.isTemporary()) {
  448   		storeFieldAction.actionPerformed
  449   		    (new ActionEvent(e.getSource(), 0, ""));
  450   	    }
  451   	}
  452   
  453       }
  454   
  455       class FieldPanel extends JPanel {
  456   
  457   	/*
  458   	 * This extension to JPanel keeps a reference to its active
  459   	 * field, on behalf of which it requests the focus when
  460   	 * it is told to.
  461   	 */
  462   
  463   	FieldEditor activeField = null;
  464   	JScrollPane sp;
  465   
  466   	public JComponent getPane() {
  467   	    return this; // Component to add. Return the scrollpane, if there is one.
  468   	}
  469   
  470   	public void setActive(FieldEditor c) {
  471   	    activeField = c;
  472   	}
  473   
  474       public Vector getFields(){
  475           Vector textFields  = new Vector() ;  
  476           Component[] components = this.getComponents() ; 
  477   
  478           try{
  479               for(int i = 0 ; i < components.length ; i++){
  480                   if(components[i]  instanceof FieldEditor){
  481                       textFields.add(components[i]) ; 
  482                   }
  483   		//else if ((components[i] instanceof JScrollPane)) {
  484   		//    Util.pr(((JScrollPane)components[i]).getViewport().getComponent(0).toString().substring(0,50));
  485   		//}
  486   		else if (components[i] instanceof JScrollPane) {
  487   		    textFields.add(((JScrollPane)components[i]).getViewport()
  488   				   .getComponent(0));
  489   		}
  490   	    }
  491               
  492   
  493               return textFields ; 
  494           }catch(ClassCastException cce){
  495               System.err.println("caught in getFields: "+cce) ; 
  496           }
  497           return null ; 
  498       }
  499   
  500   
  501       
  502   	public void activate() {
  503   	    if (activeField != null)
  504   		activeField.requestFocus();
  505   	}
  506   
  507       }
  508   
  509       class TabListener implements ChangeListener {
  510   	public void stateChanged(ChangeEvent e) {
  511   	    if (((JTabbedPane)e.getSource()).getSelectedIndex() < 3) {
  512   		FieldPanel fp = (FieldPanel)(((JTabbedPane)e.getSource()).getSelectedComponent());
  513   		fp.activate();
  514   	    } else {
  515   		source.requestFocus();
  516   	    }
  517   	}
  518       }
  519   
  520       
  521   
  522       class CloseAction extends AbstractAction {
  523   	public CloseAction() {
  524   	    super("Close window", 
  525   		  new ImageIcon(GUIGlobals.closeIconFile));
  526   	    putValue(SHORT_DESCRIPTION, "Close window (Ctrl-Q)");
  527   	}    
  528   	public void actionPerformed(ActionEvent e) {
  529   	    if (tabbed.getSelectedComponent() == srcPanel) {
  530   		storeFieldAction.actionPerformed(new ActionEvent(source, 0, ""));
  531   		if (lastSourceAccepted) {
  532   		    baseFrame.entryTypeFormClosing(entry.getId());
  533   		    dispose();
  534   		}
  535   	    } else {
  536   		baseFrame.entryTypeFormClosing(entry.getId());
  537   		dispose();
  538   	    }
  539   	}
  540       }
  541   
  542       class CopyKeyAction extends AbstractAction {
  543   	public CopyKeyAction() {
  544   	    super("Copy BibTeX key to clipboard",
  545   		  new ImageIcon(GUIGlobals.copyKeyIconFile));
  546   	    putValue(SHORT_DESCRIPTION, "Copy BibTeX key to clipboard (Ctrl-K)");
  547   	    //putValue(MNEMONIC_KEY, GUIGlobals.copyKeyCode);
  548   	}
  549   
  550      
  551   	public void actionPerformed(ActionEvent e) {
  552   	    String s = (String)(entry.getField(KEY_PROPERTY));
  553   	    StringSelection ss = new StringSelection(s);
  554   	    if (s != null) {
  555   		Toolkit.getDefaultToolkit().getSystemClipboard().setContents(ss,ss);
  556   	    }
  557   	}
  558       }
  559   
  560   
  561   
  562   
  563       class StoreFieldAction extends AbstractAction {
  564   	JDialog parent;
  565   	public StoreFieldAction(JDialog parent) {
  566   	    super("Store field value");
  567   	    this.parent = parent;
  568   	    putValue(SHORT_DESCRIPTION, "Store field value");
  569   	}
  570   	public void actionPerformed(ActionEvent e) {
  571   	    if (e.getSource() instanceof FieldEditor) {
  572   		String toSet = null, fieldName = null;
  573   		FieldEditor fe = (FieldEditor)e.getSource();
  574   		boolean set;
  575   		if (fe.getText().length() > 0)
  576   		    toSet = fe.getText();
  577   		// We check if the field has changed, since we don't want to mark the
  578   		// base as changed unless we have a real change.
  579   		if (toSet == null) {
  580   		    if (entry.getField(fe.getFieldName()) == null)
  581   			set = false;
  582   		    else
  583   			set = true;
  584   		} else {
  585   		    if ((entry.getField(fe.getFieldName()) != null)
  586   			&& toSet.equals(entry.getField(fe.getFieldName()).toString()))
  587   			set = false;
  588   		    else
  589   			set = true;
  590   		}
  591   		
  592   		if (set) try {
  593   
  594   		    // The following statement attempts to write the
  595   		    // new contents into a StringWriter, and this will
  596   		    // cause an IOException if the field is not
  597   		    // properly formatted. If that happens, the field
  598   		    // is not stored and the textarea turns red.
  599   
  600   		    if (toSet != null)
  601   			(new LatexFieldFormatter()).format(toSet);
  602   		    
  603   		    Object oldValue = entry.getField(fe.getFieldName());
  604   		    entry.setField(fe.getFieldName(), toSet);
  605   		    if ((toSet != null) && (toSet.length() > 0)) {
  606   			fe.setLabelColor(GUIGlobals.validFieldColor);
  607   			fe.setBackground(GUIGlobals.validFieldBackground);
  608   		    } else {
  609   			fe.setLabelColor(GUIGlobals.nullFieldColor);
  610   			fe.setBackground(GUIGlobals.validFieldBackground);
  611   		    }
  612   		    
  613   		    // Add an UndoableFieldChange to the baseframe's undoManager.
  614   		    baseFrame.undoManager.addEdit
  615   			(new UndoableFieldChange(entry, fe.getFieldName(),
  616   						 oldValue, toSet));
  617   
  618   		    baseFrame.refreshTable();
  619   		    baseFrame.markBaseChanged();
  620   
  621   		} catch (IllegalArgumentException ex) {
  622   		    baseFrame.output("Invalid field format: "+ex.getMessage());
  623   		    fe.setLabelColor(GUIGlobals.invalidFieldColor);
  624   		    fe.setBackground(GUIGlobals.invalidFieldBackground);
  625   		} /*catch (java.io.IOException ex2) {
  626   		    fe.setLabelColor(GUIGlobals.invalidFieldColor);
  627   		    fe.setBackground(GUIGlobals.invalidFieldBackground);		
  628   		    }*/
  629   		else {
  630   		    // set == false
  631   		    // We set the field and label color.
  632   		    fe.setBackground(GUIGlobals.validFieldBackground);
  633   		    fe.setLabelColor((toSet == null) ?
  634   				     GUIGlobals.nullFieldColor :
  635   				     GUIGlobals.validFieldColor);
  636   		}
  637   			    
  638   	    } else if ((source.isEditable()) 
  639   		       && (source.getText() != lastSourceStringAccepted)) {
  640   		// Store edited bibtex code.
  641   		BibtexParser bp = new BibtexParser
  642   		    (new java.io.StringReader(source.getText()));	
  643   		try {
  644   		    BibtexDatabase db = bp.parse().getDatabase();
  645   		    if (db.getEntryCount() > 1)
  646   			throw new Exception("More than one entry found.");
  647   		    if (db.getEntryCount() < 1)
  648   			throw new Exception("No entries found.");
  649   		    String id = entry.getId();
  650   
  651   		    NamedCompound compound = new NamedCompound("source edit");
  652   		    BibtexEntry nu = db.getEntryByID
  653   			((String)db.getKeySet().iterator().next());
  654   		    boolean anyChanged = false;
  655   
  656   		    // First, remove fields that the user have removed.
  657   		    Object[] fields = entry.getAllFields();
  658   		    for (int i=0; i<fields.length; i++)
  659   			if (GUIGlobals.isWriteableField(fields[i].toString()))
  660   			    if (nu.getField(fields[i].toString()) == null) {
  661   				compound.addEdit(new UndoableFieldChange
  662   						 (entry, fields[i].toString(),
  663   						  entry.getField(fields[i].toString()), 
  664   						  (Object)null));
  665   				entry.setField(fields[i].toString(), null);
  666   				anyChanged = true;
  667   			    }			
  668   
  669   		    // Then set all fields that have been set by the user.
  670   		    fields = nu.getAllFields();
  671   		    for (int i=0; i<fields.length; i++) 
  672   			if (entry.getField(fields[i].toString()) !=
  673   			    nu.getField(fields[i].toString()))
  674   			    {
  675   				compound.addEdit
  676   				    (new UndoableFieldChange
  677   				     (entry, fields[i].toString(),
  678   				      entry.getField(fields[i].toString()), 
  679   				      nu.getField(fields[i].toString())));	
  680   				entry.setField(fields[i].toString(), 
  681   					       nu.getField(fields[i].toString()));
  682   				anyChanged = true;
  683   			    }
  684   		    compound.end();
  685   		    if (anyChanged)
  686   			baseFrame.undoManager.addEdit(compound);
  687   		    lastSourceStringAccepted = source.getText();
  688   		    updateAllFields();
  689   		    lastSourceAccepted = true;
  690   
  691   		    updateSource = true;
  692   		    baseFrame.refreshTable();
  693   		    baseFrame.markBaseChanged();
  694   		} catch (Throwable ex) {
  695   		    // The source couldn't be parsed, so the user is given an
  696   		    // error message, and the choice to keep or revert the contents
  697   		    // of the source text field.
  698   		    updateSource = false;
  699   		    lastSourceAccepted = false;
  700   		    tabbed.setSelectedComponent(srcPanel);
  701   
  702   		    Object[] options = { "Edit","Revert to original source" };
  703   		    
  704   		    int answer = JOptionPane.showOptionDialog
  705   			(parent, "Error: "+ex.getMessage(),
  706   			 "Problem with parsing entry",
  707   			 JOptionPane.YES_NO_OPTION, 
  708   			 JOptionPane.ERROR_MESSAGE,null, options,options[0]);
  709   		    if (answer == 0) {
  710   			//updateSource = true;
  711   		    } else {
  712   			updateSource = true;
  713   			updateSource();
  714   		    }
  715   		}
  716   	    
  717   	    }
  718   	}
  719       }
  720   
  721       class SwitchLeftAction extends AbstractAction {
  722   	public SwitchLeftAction() {
  723   	    super("Switch to the panel to the left");
  724   	}    
  725   	public void actionPerformed(ActionEvent e) {
  726   	    int i = tabbed.getSelectedIndex();
  727   	    tabbed.setSelectedIndex((i>0 ? i-1 : tabbed.getTabCount()-1));
  728   	    if (tabbed.getSelectedComponent() instanceof FieldPanel)
  729   		((FieldPanel)tabbed.getSelectedComponent()).activate(); 
  730   	       // Set focus to the last used textfield.
  731   	}
  732       }
  733   
  734       class SwitchRightAction extends AbstractAction {
  735   	public SwitchRightAction() {
  736   	    super("Switch to the panel to the right");
  737   	}    
  738   	public void actionPerformed(ActionEvent e) {
  739   	    int i = tabbed.getSelectedIndex();
  740   	    tabbed.setSelectedIndex(i<tabbed.getTabCount()-1 ? i+1 : 0);
  741   	    if (tabbed.getSelectedComponent() instanceof FieldPanel)
  742   		((FieldPanel)tabbed.getSelectedComponent()).activate(); 
  743        	        // Set focus to the last used textfield.
  744   	}
  745       }
  746   
  747       /*
  748       class ShowReqAction extends AbstractAction {
  749   	public ShowReqAction() {
  750   	    super("Show required",
  751   		  new ImageIcon(GUIGlobals.showReqIconFile));
  752   	    putValue(SHORT_DESCRIPTION, "Show required fields");
  753   	    putValue(MNEMONIC_KEY, GUIGlobals.showReqKeyCode);
  754   	}
  755       
  756   	public void actionPerformed(ActionEvent e) {
  757   	    //System.out.println("Show required fields");
  758   	    tabbed.setSelectedIndex(REQ);
  759   	    reqPanel.activate(); // Set focus to the last used textfield.
  760   	}
  761       }
  762   
  763       class ShowOptAction extends AbstractAction {
  764   	public ShowOptAction() {
  765   	    super("Show optional", 
  766   		  new ImageIcon(GUIGlobals.showOptIconFile));
  767   	    putValue(SHORT_DESCRIPTION, "Show optional fields");
  768   	    putValue(MNEMONIC_KEY, GUIGlobals.showOptKeyCode);
  769   	}
  770       
  771   	public void actionPerformed(ActionEvent e) {
  772   	    tabbed.setSelectedIndex(OPT);
  773   	    optPanel.activate(); // Set focus to the last used textfield.
  774   	}
  775       }
  776   
  777   
  778       class ShowGenAction extends AbstractAction {
  779   	public ShowGenAction() {
  780   	    super("Show general", 
  781   		  new ImageIcon(GUIGlobals.showGenIconFile));
  782   	    putValue(SHORT_DESCRIPTION, "Show general fields");
  783   	    putValue(MNEMONIC_KEY, GUIGlobals.showGenKeyCode);
  784   	}
  785       
  786   	public void actionPerformed(ActionEvent e) {
  787   	    tabbed.setSelectedIndex(GEN);
  788   	    genPanel.activate(); // Set focus to the last used textfield.
  789   	}
  790       }
  791       */
  792   
  793   
  794       class GenerateKeyAction extends AbstractAction {
  795           BibtexBaseFrame parent ; 
  796           BibtexEntry selectedEntry ; 
  797   //        public GenerateKeyAction(BibtexBaseFrame parentFrame,BibtexEntry newEntry) {
  798           public GenerateKeyAction(BibtexBaseFrame parentFrame) {
  799               super("Generate Bibtexkey", 
  800                 new ImageIcon(GUIGlobals.genKeyIconFile));
  801               parent = parentFrame ; 
  802   //            selectedEntry = newEntry ; 
  803               putValue(SHORT_DESCRIPTION, "Generate Bibtexkey (Ctrl-G)");
  804       //        putValue(MNEMONIC_KEY, GUIGlobals.showGenKeyCode);
  805           }
  806       
  807           public void actionPerformed(ActionEvent e) {
  808       //        tabbed.setSelectedIndex(GEN);
  809       //        genPanel.activate(); // Set focus to the last used textfield.
  810   //            JOptionPane.showMessageDialog(parent, "Geneting a key for this field ","Close", JOptionPane.INFORMATION_MESSAGE);
  811      			// 1. get Bitexentry for selected index (already have)
  812               // 2. run the LabelMaker by it
  813   //            LabelMaker labelMaker = new LabelMaker() ; 
  814   //            System.out.println("the entry: "+selectedEntry) ; 
  815   //            selectedEntry = labelMaker.applyRule(selectedEntry) ; 
  816              try {
  817                  // this updates the table automatically, on close, but not within the tab
  818   	       Object oldValue = entry.getField(GUIGlobals.KEY_FIELD);
  819   	       entry = parent.labelMaker.applyRule(entry) ; 
  820   	       
  821   	       // Store undo information:
  822   	       parent.undoManager.addEdit(new UndoableFieldChange
  823   					  (entry, GUIGlobals.KEY_FIELD, oldValue, 
  824   					   entry.getField(GUIGlobals.KEY_FIELD)));
  825   
  826               // here we update the field
  827   			String bibtexKeyData = (String) entry.getField(BibtexBaseFrame.KEY_PROPERTY) ; 
  828               // set the field named for "bibtexkey"
  829   			setField(BibtexBaseFrame.KEY_PROPERTY,bibtexKeyData) ;
  830   			baseFrame.markBaseChanged();
  831   			baseFrame.refreshTable();
  832              }
  833              catch (Throwable t){
  834   	                System.err.println("error setting key: " +t) ; 			
  835              }
  836           }
  837       }
  838   
  839       UndoAction undoAction = new UndoAction();
  840       class UndoAction extends AbstractAction {
  841   	public UndoAction() {
  842   	    super("Undo", new ImageIcon(GUIGlobals.undoIconFile));
  843   	    putValue(SHORT_DESCRIPTION, "Undo");
  844   	}    
  845   	public void actionPerformed(ActionEvent e) {
  846   	    baseFrame.undoAction.actionPerformed(null);
  847   	}
  848       }
  849   
  850       RedoAction redoAction = new RedoAction();
  851       class RedoAction extends AbstractAction {
  852   	public RedoAction() {
  853   	    super("Undo", new ImageIcon(GUIGlobals.redoIconFile));
  854   	    putValue(SHORT_DESCRIPTION, "Redo");
  855   	}    
  856   	public void actionPerformed(ActionEvent e) {
  857   	    baseFrame.redoAction.actionPerformed(null);
  858   	}
  859       }
  860   
  861       public boolean setField(String fieldName, String newFieldData){
  862           // iterate through all tabs and fields within those tabs until we get 
  863           // the appropriate field name.  
  864           // Thanks to reflection, this shouldn't be too bad
  865   
  866           // search each panel individually
  867    
  868           try{
  869   
  870   	    if (setFieldInPanel(reqPanel, fieldName, newFieldData))
  871   		return true;
  872   	    if (setFieldInPanel(optPanel, fieldName, newFieldData))
  873   		return true;
  874   	    if (setFieldInPanel(genPanel, fieldName, newFieldData))
  875   		return true;
  876   
  877           }catch(ClassCastException cce){
  878   			System.err.println("caught in setField: "+cce) ; 
  879               return false ; 
  880           }
  881   
  882           return false ; 
  883       }
  884   
  885       private boolean setFieldInPanel(FieldPanel pan, String fieldName, 
  886   				    String newFieldData) throws ClassCastException {
  887   	Vector fields = pan.getFields() ; 
  888   	for(int i = 0 ; i < fields.size() ; i++){
  889   	    if(((FieldEditor) fields.elementAt(i)).getFieldName().equals(fieldName)){
  890   		((FieldEditor) fields.elementAt(i)).setText(newFieldData) ;
  891   		return true ; 
  892   	    }
  893   	}
  894   	return false; // Nothing found.
  895       }
  896   
  897       private void updateAllFields() {
  898   	FieldPanel[] panels = new FieldPanel[] {reqPanel, optPanel, genPanel};
  899   	for (int i=0; i<panels.length; i++) {
  900   	    Vector fields = panels[i].getFields();
  901   	    for (int j=0; j<fields.size(); j++) {
  902   		FieldEditor ed = (FieldEditor)fields.elementAt(j);
  903   		Object content = entry.getField(ed.getFieldName());
  904   		ed.setText(content == null ? "" : content.toString());
  905   		//if (ed.getFieldName().equals("year"))
  906   		//    Util.pr(content.toString());
  907   	    }
  908   	}
  909       }
  910   
  911       // Update the JTextArea when a field has changed.
  912       public void vetoableChange(PropertyChangeEvent e) {
  913   	setField(e.getPropertyName(), (String)(e.getNewValue())); 
  914   	//Util.pr(e.getPropertyName());
  915       }
  916   
  917   }

Save This Page
Home » openjdk-7 » net » sf » bibkeeper » [javadoc | source]