79359e5a0194a679bd08f049eec3de87e450b9e7
[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
99         list.setMaximumRowCount(35);
100
101         /*
102          * list.getInputMap().put(Globals.prefs.getKey("Select value"),
103          * "enter"); list.getActionMap().put("enter", new EnterAction());
104          * System.out.println(Globals.prefs.getKey("Select value"));
105          */
106         updateList();
107         // else
108         // list = new JComboBox(items.toArray());
109         con.gridwidth = m_horizontalLayout ? 3 : GridBagConstraints.REMAINDER;
110         con.fill = GridBagConstraints.HORIZONTAL;
111         con.weightx = 1;
112         // list.setPreferredSize(new Dimension(140,
113         // list.getPreferredSize().height));
114         gbl.setConstraints(list, con);
115         list.addActionListener(this);
116
117         add(list);
118
119         if (m_horizontalLayout)
120             add(Box.createHorizontalStrut(Sizes.dialogUnitXAsPixel(2,this)));
121
122         manage = new JButton(Globals.lang("Manage"));
123         gbl.setConstraints(manage, con);
124         add(manage);
125
126         manage.addActionListener(new ActionListener() {
127             public void actionPerformed(ActionEvent e) {
128                 // m_owner is either a Frame or a Dialog
129                 ContentSelectorDialog2 csd = m_owner instanceof Frame ?
130                         new ContentSelectorDialog2(
131                         (Frame) m_owner, m_frame, m_panel, true, m_metaData,
132                         m_editor.getFieldName())
133                         : new ContentSelectorDialog2((Dialog) m_owner, m_frame,
134                                 m_panel, true, m_metaData, m_editor
135                                         .getFieldName());
136                 Util.placeDialog(csd, m_frame);
137                 csd.setVisible(true); // csd.show(); -> deprecated since 1.5
138                 updateList();
139             }
140         });
141     }
142
143     public void updateList() {
144         list.removeAllItems();
145         list.addItem(""); // (Globals.lang(""));
146         Vector items = m_metaData.getData(Globals.SELECTOR_META_PREFIX
147                 + m_editor.getFieldName());
148         if ((items != null) && (items.size() > 0)) {
149             for (int i = 0; i < items.size(); i++)
150                 list.addItem(items.elementAt(i));
151         }
152     }
153
154     public void actionPerformed(ActionEvent e) {
155         if (e.getActionCommand().equals("comboBoxChanged")
156                 && (e.getModifiers() == 0))
157             // These conditions signify arrow key navigation in the dropdown
158             // list, so we should
159             // not react to it. I'm not sure if this is well defined enough to
160             // be guaranteed to work
161             // everywhere.
162             return;
163
164         if (list.getSelectedIndex() == 0)
165             return; // The first element is only for show.
166
167         String chosen = (String) list.getSelectedItem();
168         // System.out.println(list.getSelectedIndex()+"\t"+chosen);
169         if (chosen == null)
170             return;
171         if (list.getSelectedIndex() == -1) { // User edited in a new word.
172             // Add this.
173             addWord(chosen);
174             /*
175              * Vector items = metaData.getData(Globals.SELECTOR_META_PREFIX+
176              * editor.getFieldName()); boolean exists = false; int pos = -1; for
177              * (int i=0; i<items.size(); i++) { String s =
178              * (String)items.elementAt(i); if (s.equals(chosen)) { exists =
179              * true; break; } if
180              * (s.toLowerCase().compareTo(chosen.toLowerCase()) < 0) pos = i+1; }
181              * if (!exists) { items.add(Math.max(0, pos), chosen);
182              * parent.panel.markNonUndoableBaseChanged(); updateList(); }
183              */
184         }
185         if (!m_editor.getText().equals(""))
186             m_editor.append(DELIMITER);
187         m_editor.append(chosen + DELIMITER_2);
188         list.setSelectedIndex(0);
189         if (m_action != null)
190             m_action.actionPerformed(new ActionEvent(m_editor, 0, ""));
191
192         // Transfer focus to the editor.
193         m_editor.requestFocus();
194         // new FocusRequester(editor.getTextComponent());
195     }
196
197     /**
198      * Adds a word to the selector (to the JList and to the MetaData), unless it
199      * is already there
200      *
201      * @param newWord
202      *            String Word to add
203      */
204     public void addWord(String newWord) {
205
206         Vector items = m_metaData.getData(Globals.SELECTOR_META_PREFIX
207                 + m_editor.getFieldName());
208         boolean exists = false;
209         int pos = -1;
210         for (int i = 0; i < items.size(); i++) {
211             String s = (String) items.elementAt(i);
212             if (s.equals(newWord)) {
213                 exists = true;
214                 break;
215             }
216             if (s.toLowerCase().compareTo(newWord.toLowerCase()) < 0)
217                 pos = i + 1;
218         }
219         if (!exists) {
220             items.add(Math.max(0, pos), newWord);
221             m_panel.markNonUndoableBaseChanged();
222             m_panel.updateAllContentSelectors();
223             // updateList();
224         }
225
226     }
227
228     /*
229      * class EnterAction extends AbstractAction { public void
230      * actionPerformed(ActionEvent e) { System.out.println("enter");
231      * ths.actionPerformed(e); } }
232      */
233
234     /*
235      * public void popupMenuWillBecomeVisible(PopupMenuEvent e) {
236      * System.out.println("visible"); } public void
237      * popupMenuWillBecomeInvisible(PopupMenuEvent e) {
238      * System.out.println("invisible"); } public void
239      * popupMenuCanceled(PopupMenuEvent e) { System.out.println("canceled"); }
240      */
241 }