7cb8951e051e07470142bf5a55bd102d9eccf17c
[debian/jabref.git] / src / java / net / sf / jabref / TableColumnsTab.java
1 package net.sf.jabref;
2
3 import java.util.Vector;
4 import javax.swing.*;
5 import javax.swing.table.*;
6 import java.awt.*;
7 import java.awt.event.*;
8 import com.jgoodies.forms.layout.*;
9 import com.jgoodies.forms.factories.*;
10 import com.jgoodies.forms.builder.*;
11
12 class TableColumnsTab extends JPanel implements PrefsTab {
13
14     JabRefPreferences _prefs;
15     private String[] _choices;
16     private boolean tableChanged = false;
17     private JTable colSetup;
18     private int rowCount = -1, ncWidth = -1;
19     private Vector tableRows = new Vector(10);
20     private Font font = GUIGlobals.CURRENTFONT, menuFont;
21     private JabRefFrame frame;
22     private int oldMenuFontSize;
23
24     class TableRow {
25         String name;
26         int length;
27         public TableRow(String name) {
28             this.name = name;
29             length = GUIGlobals.DEFAULT_FIELD_LENGTH;
30         }
31         public TableRow(int length) {
32             this.length = length;
33             name = "";
34         }
35         public TableRow(String name, int length) {
36             this.name = name;
37             this.length = length;
38         }
39     }
40
41
42     /**
43      * Customization of external program paths.
44      *
45      * @param prefs a <code>JabRefPreferences</code> value
46      */
47     public TableColumnsTab(JabRefPreferences prefs, JabRefFrame frame) {
48         _prefs = prefs;
49         this.frame = frame;
50         setLayout(new BorderLayout());
51
52         TableModel tm = new AbstractTableModel() {
53                 public int getRowCount() { return rowCount; }
54                 public int getColumnCount() { return 2; }
55                 public Object getValueAt(int row, int column) {
56                   if (row == 0)
57                     return (column==0 ? GUIGlobals.NUMBER_COL : ""+ncWidth);
58                   row--;
59                   if (row >= tableRows.size())
60                     return "";
61                   Object rowContent = tableRows.elementAt(row);
62                   if (rowContent == null)
63                     return "";
64                   TableRow tr = (TableRow)rowContent;
65                   switch (column) {
66                     case 0:
67                       return tr.name;
68                     case 1:
69                       return ((tr.length > 0) ? Integer.toString(tr.length) : "");
70                   }
71                   return null; // Unreachable.
72                 }
73
74                 public String getColumnName(int col) {
75                     return (col == 0 ? Globals.lang("Field name") : Globals.lang("Column width"));
76                 }
77                 public Class getColumnClass(int column) {
78                     if (column == 0) return String.class;
79                     else return Integer.class;
80                 }
81                 public boolean isCellEditable(int row, int col) {
82                     return !((row == 0) && (col == 0));
83                 }
84                 public void setValueAt(Object value, int row, int col) {
85                     tableChanged = true;
86                     // Make sure the vector is long enough.
87                     while (row >= tableRows.size())
88                         tableRows.add(new TableRow("", -1));
89
90                         if ((row == 0) && (col == 1)) {
91                           ncWidth = Integer.parseInt(value.toString());
92                           return;
93                         }
94
95                     TableRow rowContent = (TableRow)tableRows.elementAt(row-1);
96
97                     if (col == 0) {
98                         rowContent.name = value.toString();
99                         if (((String)getValueAt(row, 1)).equals(""))
100                             setValueAt(""+GUIGlobals.DEFAULT_FIELD_LENGTH, row, 1);
101                     }
102                     else {
103                         if (value == null) rowContent.length = -1;
104                         else rowContent.length = Integer.parseInt(value.toString());
105                     }
106                 }
107
108             };
109
110         colSetup = new JTable(tm);
111         TableColumnModel cm = colSetup.getColumnModel();
112         cm.getColumn(0).setPreferredWidth(140);
113         cm.getColumn(1).setPreferredWidth(80);
114
115         FormLayout layout = new FormLayout
116             ("1dlu, 8dlu, left:pref, 4dlu, fill:pref",//, 4dlu, fill:60dlu, 4dlu, fill:pref",
117              "");
118         DefaultFormBuilder builder = new DefaultFormBuilder(layout);
119         JLabel lab;
120         JPanel pan = new JPanel();
121
122
123         JPanel tabPanel = new JPanel();
124         tabPanel.setLayout(new BorderLayout());
125         JScrollPane sp = new JScrollPane
126             (colSetup, JScrollPane.VERTICAL_SCROLLBAR_AS_NEEDED,
127              JScrollPane.HORIZONTAL_SCROLLBAR_NEVER);
128         colSetup.setPreferredScrollableViewportSize(new Dimension(250,200));
129         sp.setMinimumSize(new Dimension(250,300));
130         tabPanel.add(sp, BorderLayout.CENTER);
131         JToolBar tlb = new JToolBar(SwingConstants.VERTICAL);
132         tlb.setFloatable(false);
133         //tlb.setRollover(true);
134         //tlb.setLayout(gbl);
135         AddRowAction ara = new AddRowAction();
136         DeleteRowAction dra = new DeleteRowAction();
137         tlb.setBorder(null);
138         tlb.add(ara);
139         tlb.add(dra);
140         //tlb.addSeparator();
141         //tlb.add(new UpdateWidthsAction());
142         tabPanel.add(tlb, BorderLayout.EAST);
143
144         builder.appendSeparator(Globals.lang("Entry table columns"));
145         builder.nextLine();
146         builder.append(pan); builder.append(tabPanel); builder.nextLine();
147 //      lab = new JLabel("<HTML>("+Globals.lang("this button will update the column width settings<BR>"
148 //                                              +"to match the current widths in your table")+")</HTML>");
149 //        lab = new JLabel("<HTML>("+Globals.lang("this_button_will_update") +")</HTML>") ;
150         builder.append(pan);
151         JButton button = new JButton(new UpdateWidthsAction());
152         builder.append(button); builder.nextLine();
153         builder.append(pan); 
154         //builder.append(lab);
155         builder.nextLine();
156         pan = builder.getPanel();
157         pan.setBorder(BorderFactory.createEmptyBorder(5,5,5,5));
158         add(pan, BorderLayout.CENTER);
159     }
160
161     public void setValues() {
162         tableRows.clear();
163         String[] names = _prefs.getStringArray("columnNames"),
164             lengths = _prefs.getStringArray("columnWidths");
165         for (int i=0; i<names.length; i++) {
166             if (i<lengths.length)
167                 tableRows.add(new TableRow(names[i], Integer.parseInt(lengths[i])));
168             else
169                 tableRows.add(new TableRow(names[i]));
170         }
171         rowCount = tableRows.size()+5;
172         ncWidth = _prefs.getInt("numberColWidth");
173
174     }
175
176
177     class DeleteRowAction extends AbstractAction {
178         public DeleteRowAction() {
179           super("Delete row", GUIGlobals.getImage("remove"));
180           putValue(SHORT_DESCRIPTION, Globals.lang("Delete rows"));
181         }
182         public void actionPerformed(ActionEvent e) {
183           int[] rows = colSetup.getSelectedRows();
184           if (rows.length == 0)
185             return;
186           int offs = 0;
187           for (int i=rows.length-1; i>=0; i--) {
188             if ((rows[i] <= tableRows.size()) && (rows[i] != 0)) {
189                 tableRows.remove(rows[i]-1);
190                 offs++;
191             }
192           }
193           rowCount -= offs;
194           if (rows.length > 1) colSetup.clearSelection();
195           colSetup.revalidate();
196           colSetup.repaint();
197           tableChanged = true;
198         }
199       }
200
201     class AddRowAction extends AbstractAction {
202         public AddRowAction() {
203           super("Add row", GUIGlobals.getImage("add"));
204           putValue(SHORT_DESCRIPTION, Globals.lang("Insert rows"));
205         }
206         public void actionPerformed(ActionEvent e) {
207             int[] rows = colSetup.getSelectedRows();
208             if (rows.length == 0) {
209                 // No rows selected, so we just add one at the end.
210                 rowCount++;
211                 colSetup.revalidate();
212                 colSetup.repaint();
213                 return;
214             }
215             for (int i=0; i<rows.length; i++) {
216                 if (rows[i]+i-1 < tableRows.size())
217                     tableRows.add(Math.max(0, rows[i]+i-1), new TableRow(GUIGlobals.DEFAULT_FIELD_LENGTH));
218             }
219             rowCount += rows.length;
220             if (rows.length > 1) colSetup.clearSelection();
221             colSetup.revalidate();
222             colSetup.repaint();
223             tableChanged = true;
224         }
225     }
226
227     class UpdateWidthsAction extends AbstractAction {
228         public UpdateWidthsAction() {
229           //super(Globals.lang("Update to current column widths"));
230           super(Globals.lang("Update to current column widths"));
231           //putValue(SHORT_DESCRIPTION, Globals.lang("Update to current column widths"));
232         }
233         public void actionPerformed(ActionEvent e) {
234             BasePanel panel = frame.basePanel();
235             if (panel == null) return;
236             TableColumnModel colMod = panel.mainTable.getColumnModel();
237             colSetup.setValueAt(""+colMod.getColumn(0).getWidth(), 0, 1);
238             for (int i=1; i<colMod.getColumnCount(); i++) {
239             try {
240                 String name = panel.mainTable.getColumnName(i).toLowerCase();
241                 int width = colMod.getColumn(i).getWidth();
242                 //Util.pr(":"+((String)colSetup.getValueAt(i-1, 0)).toLowerCase());
243                 //Util.pr("-"+name);
244                 if ((i <= tableRows.size()) && (((String)colSetup.getValueAt(i, 0)).toLowerCase()).equals(name))
245                     colSetup.setValueAt(""+width, i, 1);
246                 else { // Doesn't match; search for a matching col in our table
247                     for (int j=0; j<colSetup.getRowCount(); j++) {
248                         if ((j < tableRows.size()) &&
249                             (((String)colSetup.getValueAt(j, 0)).toLowerCase()).equals(name)) {
250                             colSetup.setValueAt(""+width, j, 1);
251                             break;
252                         }
253                     }
254                 }
255             } catch (Throwable ex) {
256                 ex.printStackTrace();
257             }
258             colSetup.revalidate();
259             colSetup.repaint();
260         }
261
262         }
263     }
264
265  
266     /**
267      * Store changes to table preferences. This method is called when
268      * the user clicks Ok.
269      *
270      */
271     public void storeSettings() {
272
273         if (colSetup.isEditing()) {
274             int col = colSetup.getEditingColumn(),
275                 row = colSetup.getEditingRow();
276             colSetup.getCellEditor(row, col).stopCellEditing();
277         }
278
279
280         //_prefs.putStringArray("columnNames", getChoices());
281         /*String[] cols = tableFields.getText().replaceAll("\\s+","")
282             .replaceAll("\\n+","").toLowerCase().split(";");
283         if (cols.length > 0) for (int i=0; i<cols.length; i++)
284             cols[i] = cols[i].trim();
285             else cols = null;*/
286
287         // Now we need to make sense of the contents the user has made to the
288         // table setup table.
289         if (tableChanged) {
290             // First we remove all rows with empty names.
291             int i=0;
292             while (i < tableRows.size()) {
293                 if (((TableRow)tableRows.elementAt(i)).name.equals(""))
294                     tableRows.removeElementAt(i);
295                 else i++;
296             }
297             // Then we make arrays
298             String[] names = new String[tableRows.size()],
299                 widths = new String[tableRows.size()];
300             int[] nWidths = new int[tableRows.size()];
301
302             _prefs.putInt("numberColWidth", ncWidth);
303             for (i=0; i<tableRows.size(); i++) {
304                 TableRow tr = (TableRow)tableRows.elementAt(i);
305                 names[i] = tr.name;
306                 nWidths[i] = tr.length;
307                 widths[i] = ""+tr.length;
308                 //Util.pr(names[i]+"   "+widths[i]);
309             }
310
311             // Finally, we store the new preferences.
312             _prefs.putStringArray("columnNames", names);
313             _prefs.putStringArray("columnWidths", widths);
314         }
315
316     }
317
318     public boolean readyToClose() {
319         return true;
320     }
321
322 }
323
324         /*
325         Boolean[] sel = new Boolean[GUIGlobals.ALL_FIELDS.length];
326         boolean found;
327         _choices = GUIGlobals.ALL_FIELDS;
328         _sel = sel;
329         String[] columns = prefs.getStringArray("columnNames");
330         for (int i=0; i<_choices.length; i++) {
331             found = false;
332             for (int j=0; j<columns.length; j++)
333                 if (columns[j].equals(_choices[i]))
334                     found = true;
335             if (found)
336                 sel[i] = new Boolean(true);
337             else
338                 sel[i] = new Boolean(false);
339         }
340
341         TableModel tm = new AbstractTableModel() {
342                 public int getRowCount() { return (_choices.length-1)/2; }
343                 public int getColumnCount() { return 4; }
344                 public Object getValueAt(int row, int column) {
345                     switch (column) {
346                     case 0:
347                         return _choices[row];
348                     case 1:
349                         return _sel[row];
350                     case 2:
351                         return _choices[getRowCount()+row];
352                     case 3:
353                         return _sel[getRowCount()+row];
354                     }
355                     return null; // Unreachable.
356                 }
357                 public Class getColumnClass(int column) {
358                     if ((column == 0) || (column == 2)) return String.class;
359                     else return Boolean.class;
360                 }
361                 public boolean isCellEditable(int row, int col) {
362                     if ((col == 1) || (col == 3)) return true;
363                     else return false;
364                 }
365                 public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
366                     if (columnIndex == 1)
367                         _sel[rowIndex] = (Boolean)aValue;
368                     if (columnIndex == 3)
369                         _sel[getRowCount()+rowIndex] = (Boolean)aValue;
370                 }
371
372             };
373
374         JTable table = new JTable(tm);
375         table.setRowSelectionAllowed(false);
376         table.setColumnSelectionAllowed(false);
377         //table.getInputMap().put(GUIGlobals.exitDialog, "close");
378         //table.getActionMap().put("close", new CancelAction());
379         JPanel
380             tablePanel = new JPanel(),
381             innerTablePanel = new JPanel();
382
383         table.setShowVerticalLines(false);
384         innerTablePanel.setBorder(BorderFactory.createEtchedBorder());
385         //innerTablePanel.setBorder(BorderFactory.createLoweredBevelBorder());
386         innerTablePanel.add(table);
387         tablePanel.add(innerTablePanel);
388
389
390         TableColumnModel cm = table.getColumnModel();
391         cm.getColumn(0).setPreferredWidth(90);
392         cm.getColumn(1).setPreferredWidth(25);
393         cm.getColumn(2).setPreferredWidth(90);
394         cm.getColumn(3).setPreferredWidth(25);
395         */