8150ca8e42475c552ebbba34d6c04b5498f139b1
[debian/jabref.git] / src / java / net / sf / jabref / FieldContentSelector.java
1 /*
2  Copyright (C) 2003 Morten O. Alver, Nizar N. Batada
3
4  All programs in this directory and
5  subdirectories are published under the GNU General Public License as
6  described below.
7
8  This program is free software; you can redistribute it and/or modify
9  it under the terms of the GNU General Public License as published by
10  the Free Software Foundation; either version 2 of the License, or (at
11  your option) any later version.
12
13  This program is distributed in the hope that it will be useful, but
14  WITHOUT ANY WARRANTY; without even the implied warranty of
15  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  General Public License for more details.
17
18  You should have received a copy of the GNU General Public License
19  along with this program; if not, write to the Free Software
20  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
21  USA
22
23  Further information about the GNU GPL is available at:
24  http://www.gnu.org/copyleft/gpl.ja.html
25
26  */
27 package net.sf.jabref;
28
29 import java.awt.*;
30 import java.awt.event.*;
31 import java.util.Vector;
32
33 import javax.swing.*;
34
35 import com.jgoodies.forms.layout.Sizes;
36
37 public class FieldContentSelector extends JComponent implements ActionListener {
38
39     protected final String DELIMITER = " ", DELIMITER_2 = "";
40     protected final FieldEditor m_editor;
41     JComboBox list = new JComboBox() {
42         public Dimension getPreferredSize() {
43             Dimension parents = super.getPreferredSize();
44             if (parents.width > GUIGlobals.MAX_CONTENT_SELECTOR_WIDTH)
45                 parents.width = GUIGlobals.MAX_CONTENT_SELECTOR_WIDTH;
46             return parents;
47         }
48     };
49     JButton manage;
50     GridBagLayout gbl = new GridBagLayout();
51     GridBagConstraints con = new GridBagConstraints();
52     protected final MetaData m_metaData;
53     protected final JabRefFrame m_frame;
54     protected final Window m_owner; 
55     protected final BasePanel m_panel;
56     protected final AbstractAction m_action;
57     protected final boolean m_horizontalLayout;
58
59     /**
60      * @param action
61      *            The action that will be performed to conclude content
62      *            insertion.
63      */
64     public FieldContentSelector(JabRefFrame frame, BasePanel panel,
65             Dialog owner, FieldEditor editor, MetaData data,
66             AbstractAction action, boolean horizontalLayout) {
67         m_editor = editor;
68         m_metaData = data;
69         m_action = action;
70         m_frame = frame;
71         m_panel = panel;
72         m_owner = owner;
73         m_horizontalLayout = horizontalLayout;
74         doInit();
75     }
76
77     /**
78      * @param action
79      *            The action that will be performed to conclude content
80      *            insertion.
81      */
82     public FieldContentSelector(JabRefFrame frame, BasePanel panel,
83             Frame owner, FieldEditor editor, MetaData data,
84             AbstractAction action, boolean horizontalLayout) {
85         m_editor = editor;
86         m_metaData = data;
87         m_action = action;
88         m_frame = frame;
89         m_panel = panel;
90         m_owner = owner;
91         m_horizontalLayout = horizontalLayout;
92         doInit();
93     }
94
95     private void doInit() {
96         setLayout(gbl);
97         list.setEditable(true);
98         list.setMaximumRowCount(35);
99
100         /*
101          * list.getInputMap().put(Globals.prefs.getKey("Select value"),
102          * "enter"); list.getActionMap().put("enter", new EnterAction());
103          * System.out.println(Globals.prefs.getKey("Select value"));
104          */
105         updateList();
106         // else
107         // list = new JComboBox(items.toArray());
108         con.gridwidth = m_horizontalLayout ? 3 : GridBagConstraints.REMAINDER;
109         con.fill = GridBagConstraints.HORIZONTAL;
110         con.weightx = 1;
111         // list.setPreferredSize(new Dimension(140,
112         // list.getPreferredSize().height));
113         gbl.setConstraints(list, con);
114         list.addActionListener(this);
115
116         add(list);
117         
118         if (m_horizontalLayout)
119             add(Box.createHorizontalStrut(Sizes.dialogUnitXAsPixel(2,this)));
120
121         manage = new JButton(Globals.lang("Manage"));
122         gbl.setConstraints(manage, con);
123         add(manage);
124
125         manage.addActionListener(new ActionListener() {
126             public void actionPerformed(ActionEvent e) {
127                 // m_owner is either a Frame or a Dialog
128                 ContentSelectorDialog2 csd = m_owner instanceof Frame ? 
129                         new ContentSelectorDialog2(
130                         (Frame) m_owner, m_frame, m_panel, true, m_metaData,
131                         m_editor.getFieldName())
132                         : new ContentSelectorDialog2((Dialog) m_owner, m_frame,
133                                 m_panel, true, m_metaData, m_editor
134                                         .getFieldName());
135                 Util.placeDialog(csd, m_frame);
136                 csd.show();
137                 updateList();
138             }
139         });
140     }
141
142     public void updateList() {
143         list.removeAllItems();
144         list.addItem(""); // (Globals.lang(""));
145         Vector items = m_metaData.getData(Globals.SELECTOR_META_PREFIX
146                 + m_editor.getFieldName());
147         if ((items != null) && (items.size() > 0)) {
148             for (int i = 0; i < items.size(); i++)
149                 list.addItem(items.elementAt(i));
150         }
151     }
152
153     public void actionPerformed(ActionEvent e) {
154         if (e.getActionCommand().equals("comboBoxChanged")
155                 && (e.getModifiers() == 0))
156             // These conditions signify arrow key navigation in the dropdown
157             // list, so we should
158             // not react to it. I'm not sure if this is well defined enough to
159             // be guaranteed to work
160             // everywhere.
161             return;
162
163         if (list.getSelectedIndex() == 0)
164             return; // The first element is only for show.
165
166         String chosen = (String) list.getSelectedItem();
167         // System.out.println(list.getSelectedIndex()+"\t"+chosen);
168         if (chosen == null)
169             return;
170         if (list.getSelectedIndex() == -1) { // User edited in a new word.
171             // Add this.
172             addWord(chosen);
173             /*
174              * Vector items = metaData.getData(Globals.SELECTOR_META_PREFIX+
175              * editor.getFieldName()); boolean exists = false; int pos = -1; for
176              * (int i=0; i<items.size(); i++) { String s =
177              * (String)items.elementAt(i); if (s.equals(chosen)) { exists =
178              * true; break; } if
179              * (s.toLowerCase().compareTo(chosen.toLowerCase()) < 0) pos = i+1; }
180              * if (!exists) { items.add(Math.max(0, pos), chosen);
181              * parent.panel.markNonUndoableBaseChanged(); updateList(); }
182              */
183         }
184         if (!m_editor.getText().equals(""))
185             m_editor.append(DELIMITER);
186         m_editor.append(chosen + DELIMITER_2);
187         list.setSelectedIndex(0);
188         if (m_action != null)
189             m_action.actionPerformed(new ActionEvent(m_editor, 0, ""));
190
191         // Transfer focus to the editor.
192         m_editor.requestFocus();
193         // new FocusRequester(editor.getTextComponent());
194     }
195
196     /**
197      * Adds a word to the selector (to the JList and to the MetaData), unless it
198      * is already there
199      * 
200      * @param newWord
201      *            String Word to add
202      */
203     public void addWord(String newWord) {
204
205         Vector items = m_metaData.getData(Globals.SELECTOR_META_PREFIX
206                 + m_editor.getFieldName());
207         boolean exists = false;
208         int pos = -1;
209         for (int i = 0; i < items.size(); i++) {
210             String s = (String) items.elementAt(i);
211             if (s.equals(newWord)) {
212                 exists = true;
213                 break;
214             }
215             if (s.toLowerCase().compareTo(newWord.toLowerCase()) < 0)
216                 pos = i + 1;
217         }
218         if (!exists) {
219             items.add(Math.max(0, pos), newWord);
220             m_panel.markNonUndoableBaseChanged();
221             m_panel.updateAllContentSelectors();
222             // updateList();
223         }
224
225     }
226
227     /*
228      * class EnterAction extends AbstractAction { public void
229      * actionPerformed(ActionEvent e) { System.out.println("enter");
230      * ths.actionPerformed(e); } }
231      */
232
233     /*
234      * public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
235      * System.out.println("visible"); } public void
236      * popupMenuWillBecomeInvisible(PopupMenuEvent e) {
237      * System.out.println("invisible"); } public void
238      * popupMenuCanceled(PopupMenuEvent e) { System.out.println("canceled"); }
239      */
240 }