40038686e03383392a8ca5462ced1007df9cf79b
[debian/jabref.git] / src / java / net / sf / jabref / NameFormatterTab.java
1 package net.sf.jabref;
2
3 import java.awt.BorderLayout;
4 import java.awt.Dimension;
5 import java.awt.event.ActionEvent;
6 import java.util.HashMap;
7 import java.util.Map;
8 import java.util.Vector;
9
10 import javax.swing.AbstractAction;
11 import javax.swing.BorderFactory;
12 import javax.swing.JPanel;
13 import javax.swing.JScrollPane;
14 import javax.swing.JTable;
15 import javax.swing.JToolBar;
16 import javax.swing.SwingConstants;
17 import javax.swing.table.AbstractTableModel;
18 import javax.swing.table.TableColumnModel;
19 import javax.swing.table.TableModel;
20
21 import net.sf.jabref.export.layout.format.NameFormat;
22
23 import com.jgoodies.forms.builder.DefaultFormBuilder;
24 import com.jgoodies.forms.layout.FormLayout;
25
26 public class NameFormatterTab extends JPanel implements PrefsTab {
27
28         public static final String NAME_FORMATTER_VALUE = "nameFormatterFormats";
29
30         public static final String NAME_FORMATER_KEY = "nameFormatterNames";
31
32         public static Map getNameFormatters(){
33                 
34                 Map result = new HashMap();
35
36                 String[] names = Globals.prefs.getStringArray(NAME_FORMATER_KEY);
37                 String[] formats = Globals.prefs.getStringArray(NAME_FORMATTER_VALUE);
38                 
39                 if (names == null){
40                         names = new String[]{};
41                 }
42                 if (formats == null){
43                         formats = new String[]{};
44                 }
45                 
46                 for (int i = 0; i < names.length; i++) {
47                         if (i < formats.length)
48                                 result.put(names[i], formats[i]);
49                         else
50                                 result.put(names[i], NameFormat.DEFAULT_FORMAT);
51                 }
52                 
53                 return result;
54         }
55         
56         private boolean tableChanged = false;
57
58         private JTable table;
59
60         private int rowCount = -1;
61
62         private Vector tableRows = new Vector(10);
63
64         class TableRow {
65                 String name;
66
67                 String format;
68
69                 public TableRow() {
70                         this("");
71                 }
72
73                 public TableRow(String name) {
74                         this(name, NameFormat.DEFAULT_FORMAT);
75                 }
76
77                 public TableRow(String name, String format) {
78                         this.name = name;
79                         this.format = format;
80                 }
81         }
82
83         /**
84          * Tab to create custom Name Formatters
85          * 
86          */
87         public NameFormatterTab(HelpDialog helpDialog) {
88                 setLayout(new BorderLayout());
89
90                 TableModel tm = new AbstractTableModel() {
91                         public int getRowCount() {
92                                 return rowCount;
93                         }
94
95                         public int getColumnCount() {
96                                 return 2;
97                         }
98
99                         public Object getValueAt(int row, int column) {
100                                 if (row >= tableRows.size())
101                                         return "";
102                                 TableRow tr = (TableRow) tableRows.elementAt(row);
103                                 if (tr == null)
104                                         return "";
105                                 switch (column) {
106                                 case 0:
107                                         return tr.name;
108                                 case 1:
109                                         return tr.format;
110                                 }
111                                 return null; // Unreachable.
112                         }
113
114                         public String getColumnName(int col) {
115                                 return (col == 0 ? Globals.lang("Formatter Name") : Globals.lang("Format String"));
116                         }
117
118                         public Class getColumnClass(int column) {
119                                 if (column == 0)
120                                         return String.class;
121                                 else
122                                         return String.class;
123                         }
124
125                         public boolean isCellEditable(int row, int col) {
126                                 return true;
127                         }
128
129                         public void setValueAt(Object value, int row, int col) {
130                                 tableChanged = true;
131
132                                 // Make sure the vector is long enough.
133                                 while (row >= tableRows.size())
134                                         tableRows.add(new TableRow());
135
136                                 TableRow rowContent = (TableRow) tableRows.elementAt(row);
137
138                                 if (col == 0)
139                                         rowContent.name = value.toString();
140                                 else
141                                         rowContent.format = value.toString();
142                         }
143                 };
144
145                 table = new JTable(tm);
146                 TableColumnModel cm = table.getColumnModel();
147                 cm.getColumn(0).setPreferredWidth(140);
148                 cm.getColumn(1).setPreferredWidth(400);
149
150                 FormLayout layout = new FormLayout("1dlu, 8dlu, left:pref, 4dlu, fill:pref", "");
151
152                 DefaultFormBuilder builder = new DefaultFormBuilder(layout);
153
154                 JPanel pan = new JPanel();
155
156                 JPanel tabPanel = new JPanel();
157                 tabPanel.setLayout(new BorderLayout());
158                 JScrollPane sp = new JScrollPane(table, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
159                         JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
160                 table.setPreferredScrollableViewportSize(new Dimension(250, 200));
161                 sp.setMinimumSize(new Dimension(250, 300));
162                 sp.setPreferredSize(new Dimension(600, 300));
163                 tabPanel.add(sp, BorderLayout.CENTER);
164
165                 JToolBar tlb = new JToolBar(SwingConstants.VERTICAL);
166                 tlb.setFloatable(false);
167                 tlb.setBorder(null);
168                 tlb.add(new AddRowAction());
169                 tlb.add(new DeleteRowAction());
170                 tlb.add(new HelpAction(helpDialog, GUIGlobals.nameFormatterHelp,
171                         Globals.lang("Help on Name Formatting"), GUIGlobals.getIconUrl("helpSmall")));
172
173                 tabPanel.add(tlb, BorderLayout.EAST);
174
175                 builder.appendSeparator(Globals.lang("Special Name Formatters"));
176                 builder.nextLine();
177                 builder.append(pan);
178                 builder.append(tabPanel);
179                 builder.nextLine();
180
181                 pan = builder.getPanel();
182                 pan.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
183                 add(pan, BorderLayout.CENTER);
184         }
185
186         public void setValues() {
187                 tableRows.clear();
188                 String[] names = Globals.prefs.getStringArray(NAME_FORMATER_KEY);
189                 String[] formats = Globals.prefs.getStringArray(NAME_FORMATTER_VALUE);
190                 
191                 if (names == null){
192                         names = new String[]{};
193                 }
194                 if (formats == null){
195                         formats = new String[]{};
196                 }
197                 
198                 for (int i = 0; i < names.length; i++) {
199                         if (i < formats.length)
200                                 tableRows.add(new TableRow(names[i], formats[i]));
201                         else
202                                 tableRows.add(new TableRow(names[i]));
203                 }
204                 rowCount = tableRows.size() + 5;
205         }
206
207         class DeleteRowAction extends AbstractAction {
208                 
209                 public DeleteRowAction() {
210                         super("Delete row", GUIGlobals.getImage("remove"));
211                         putValue(SHORT_DESCRIPTION, Globals.lang("Delete rows"));
212                 }
213
214                 public void actionPerformed(ActionEvent e) {
215                         tableChanged = true;
216                         
217                         int[] selectedRows = table.getSelectedRows();
218                 
219                         int numberDeleted = 0;
220                         
221                         for (int i = selectedRows.length - 1; i >= 0; i--) {
222                                 if (selectedRows[i] < tableRows.size()) {
223                                         tableRows.remove(selectedRows[i]);
224                                         numberDeleted++;
225                                 }
226                         }
227                         
228                         rowCount -= numberDeleted;
229                         
230                         if (selectedRows.length > 1)
231                                 table.clearSelection();
232                         
233                         table.revalidate();
234                         table.repaint();
235                 }
236         }
237
238         class AddRowAction extends AbstractAction {
239                 public AddRowAction() {
240                         super("Add row", GUIGlobals.getImage("add"));
241                         putValue(SHORT_DESCRIPTION, Globals.lang("Insert rows"));
242                 }
243
244                 public void actionPerformed(ActionEvent e) {
245                         int[] rows = table.getSelectedRows();
246                         if (rows.length == 0) {
247                                 // No rows selected, so we just add one at the end.
248                                 rowCount++;
249                                 table.revalidate();
250                                 table.repaint();
251                                 return;
252                         }
253                         for (int i = 0; i < rows.length; i++) {
254                                 if (rows[i] + i - 1 < tableRows.size())
255                                         tableRows.add(Math.max(0, rows[i] + i - 1), new TableRow());
256                         }
257                         rowCount += rows.length;
258                         if (rows.length > 1)
259                                 table.clearSelection();
260                         table.revalidate();
261                         table.repaint();
262                         tableChanged = true;
263                 }
264         }
265
266         /**
267          * Store changes to table preferences. This method is called when the user
268          * clicks Ok.
269          * 
270          */
271         public void storeSettings() {
272
273                 if (table.isEditing()) {
274                         int col = table.getEditingColumn(), row = table.getEditingRow();
275                         table.getCellEditor(row, col).stopCellEditing();
276                 }
277
278                 // Now we need to make sense of the contents the user has made to the
279                 // table setup table.
280                 if (tableChanged) {
281                         // First we remove all rows with empty names.
282                         int i = 0;
283                         while (i < tableRows.size()) {
284                                 if (((TableRow) tableRows.elementAt(i)).name.equals(""))
285                                         tableRows.removeElementAt(i);
286                                 else
287                                         i++;
288                         }
289                         // Then we make arrays
290                         String[] names = new String[tableRows.size()], formats = new String[tableRows.size()];
291
292                         for (i = 0; i < tableRows.size(); i++) {
293                                 TableRow tr = (TableRow) tableRows.elementAt(i);
294                                 names[i] = tr.name;
295                                 formats[i] = tr.format;
296                         }
297
298                         // Finally, we store the new preferences.
299                         Globals.prefs.putStringArray(NAME_FORMATER_KEY, names);
300                         Globals.prefs.putStringArray(NAME_FORMATTER_VALUE, formats);
301                 }
302         }
303
304         public boolean readyToClose() {
305                 return true;
306         }
307 }