001/*
002 * 
003 * This file is part of Icy.
004 * 
005 * Icy is free software: you can redistribute it and/or modify
006 * it under the terms of the GNU General Public License as published by
007 * the Free Software Foundation, either version 3 of the License, or
008 * (at your option) any later version.
009 * 
010 * Icy is distributed in the hope that it will be useful,
011 * but WITHOUT ANY WARRANTY; without even the implied warranty of
012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
013 * GNU General Public License for more details.
014 * 
015 * You should have received a copy of the GNU General Public License
016 * along with Icy. If not, see <http://www.gnu.org/licenses/>.
017 */
018package icy.gui.preferences;
019
020import icy.gui.component.IcyTable;
021import icy.plugin.PluginRepositoryLoader;
022import icy.preferences.RepositoryPreferences;
023import icy.preferences.RepositoryPreferences.RepositoryInfo;
024import icy.workspace.WorkspaceRepositoryLoader;
025
026import java.awt.BorderLayout;
027import java.awt.event.ActionEvent;
028import java.awt.event.ActionListener;
029import java.util.ArrayList;
030
031import javax.swing.BorderFactory;
032import javax.swing.Box;
033import javax.swing.BoxLayout;
034import javax.swing.JButton;
035import javax.swing.JPanel;
036import javax.swing.JScrollPane;
037import javax.swing.JTable;
038import javax.swing.ListSelectionModel;
039import javax.swing.event.ListSelectionEvent;
040import javax.swing.event.ListSelectionListener;
041import javax.swing.table.AbstractTableModel;
042import javax.swing.table.TableColumn;
043import javax.swing.table.TableColumnModel;
044
045/**
046 * @author Stephane
047 */
048public class RepositoryPreferencePanel extends PreferencePanel implements ListSelectionListener
049{
050    /**
051     * 
052     */
053    private static final long serialVersionUID = 5676905012950916850L;
054
055    public static final String NODE_NAME = "Repository";
056
057    static final String[] columnNames = {"Name", "Location", "Enabled"};
058
059    /**
060     * list of repository
061     */
062    final ArrayList<RepositoryInfo> repositories;
063
064    /**
065     * gui
066     */
067    final AbstractTableModel tableModel;
068    final JTable table;
069
070    final JButton addButton;
071    final JButton editButton;
072    final JButton removeButton;
073
074    RepositoryPreferencePanel(PreferenceFrame parent)
075    {
076        super(parent, NODE_NAME, PreferenceFrame.NODE_NAME);
077
078        repositories = new ArrayList<RepositoryInfo>();
079
080        load();
081
082        // build buttons
083        addButton = new JButton("add...");
084        addButton.setToolTipText("Add a new repository");
085        addButton.addActionListener(new ActionListener()
086        {
087            @Override
088            public void actionPerformed(ActionEvent e)
089            {
090                addRepository();
091            }
092        });
093
094        editButton = new JButton("edit...");
095        editButton.setToolTipText("Edit selected repository");
096        editButton.addActionListener(new ActionListener()
097        {
098            @Override
099            public void actionPerformed(ActionEvent e)
100            {
101                editRepository(getSelectedRepository());
102            }
103        });
104
105        removeButton = new JButton("remove");
106        removeButton.setToolTipText("Delete selected repository");
107        removeButton.addActionListener(new ActionListener()
108        {
109            @Override
110            public void actionPerformed(ActionEvent e)
111            {
112                removeRepository(getSelectedRepository());
113            }
114        });
115
116        final JPanel buttonsPanel = new JPanel();
117        buttonsPanel.setBorder(BorderFactory.createEmptyBorder(8, 8, 8, 8));
118        buttonsPanel.setLayout(new BoxLayout(buttonsPanel, BoxLayout.PAGE_AXIS));
119
120        buttonsPanel.add(addButton);
121        buttonsPanel.add(Box.createVerticalStrut(8));
122        buttonsPanel.add(editButton);
123        buttonsPanel.add(Box.createVerticalStrut(8));
124        buttonsPanel.add(removeButton);
125        buttonsPanel.add(Box.createVerticalStrut(8));
126        buttonsPanel.add(Box.createVerticalGlue());
127
128        // build table
129        tableModel = new AbstractTableModel()
130        {
131            /**
132             * 
133             */
134            private static final long serialVersionUID = -8573364273165723214L;
135
136            @Override
137            public int getColumnCount()
138            {
139                return columnNames.length;
140            }
141
142            @Override
143            public String getColumnName(int column)
144            {
145                return columnNames[column];
146            }
147
148            @Override
149            public int getRowCount()
150            {
151                return repositories.size();
152            }
153
154            @Override
155            public Object getValueAt(int row, int column)
156            {
157                final RepositoryInfo reposInf = repositories.get(row);
158
159                switch (column)
160                {
161                    case 0:
162                        return reposInf.getName();
163
164                    case 1:
165                        return reposInf.getLocation();
166
167                    case 2:
168                        return Boolean.valueOf(reposInf.isEnabled());
169
170                }
171
172                return "";
173            }
174
175            @Override
176            public boolean isCellEditable(int row, int column)
177            {
178                return (column == 2);
179            }
180
181            @Override
182            public void setValueAt(Object aValue, int rowIndex, int columnIndex)
183            {
184                final RepositoryInfo reposInf = repositories.get(rowIndex);
185
186                switch (columnIndex)
187                {
188                    case 0:
189                    case 1:
190                        // read only
191                        break;
192
193                    case 2:
194                        if (aValue instanceof Boolean)
195                            reposInf.setEnabled(((Boolean) aValue).booleanValue());
196                        break;
197                }
198            }
199
200            @Override
201            public Class<?> getColumnClass(int columnIndex)
202            {
203                if (columnIndex == 2)
204                    return Boolean.class;
205
206                return String.class;
207            }
208        };
209
210        table = new IcyTable(tableModel);
211
212        final TableColumnModel colModel = table.getColumnModel();
213        TableColumn col;
214
215        // columns setting
216        col = colModel.getColumn(0);
217        col.setMinWidth(80);
218        col.setPreferredWidth(80);
219        col.setMaxWidth(120);
220
221        col = colModel.getColumn(1);
222        col.setMinWidth(160);
223        col.setPreferredWidth(240);
224        col.setMaxWidth(500);
225
226        col = colModel.getColumn(2);
227        col.setMinWidth(60);
228        col.setPreferredWidth(60);
229        col.setMaxWidth(60);
230
231        table.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
232        table.getSelectionModel().addListSelectionListener(this);
233        table.setRowSelectionAllowed(true);
234        table.setColumnSelectionAllowed(false);
235        table.setAutoCreateRowSorter(true);
236        table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
237
238        final JPanel tablePanel = new JPanel();
239
240        tablePanel.setLayout(new BoxLayout(tablePanel, BoxLayout.PAGE_AXIS));
241
242        tablePanel.add(table.getTableHeader());
243        tablePanel.add(new JScrollPane(table));
244
245        mainPanel.setLayout(new BorderLayout());
246
247        mainPanel.add(tablePanel, BorderLayout.CENTER);
248        mainPanel.add(buttonsPanel, BorderLayout.EAST);
249
250        mainPanel.validate();
251
252        // select first entry in table
253        table.getSelectionModel().setSelectionInterval(0, 0);
254    }
255
256    @Override
257    protected void load()
258    {
259        repositories.clear();
260        repositories.addAll(RepositoryPreferences.getRepositeries());
261    }
262
263    @Override
264    protected void save()
265    {
266        // save to rpeferences
267        RepositoryPreferences.setRepositeries(repositories);
268
269        // then reload online plugins and workspace as repositories changed
270        PluginRepositoryLoader.reload();
271        WorkspaceRepositoryLoader.reload();
272
273        // update repositories on Workspace and Plugin panel
274        ((PluginLocalPreferencePanel) getPreferencePanel(PluginLocalPreferencePanel.class)).updateRepositories();
275        ((PluginOnlinePreferencePanel) getPreferencePanel(PluginOnlinePreferencePanel.class)).updateRepositories();
276        ((WorkspaceOnlinePreferencePanel) getPreferencePanel(WorkspaceOnlinePreferencePanel.class))
277                .updateRepositories();
278        ((WorkspaceLocalPreferencePanel) getPreferencePanel(WorkspaceLocalPreferencePanel.class)).updateRepositories();
279    }
280
281    private int getRepositeryIndex(RepositoryInfo reposInf)
282    {
283        return repositories.indexOf(reposInf);
284    }
285
286    private int getRepositeryModelIndex(RepositoryInfo reposInf)
287    {
288        return getRepositeryIndex(reposInf);
289    }
290
291    // private int getRepositeryTableIndex(RepositoryInfo reposInf)
292    // {
293    // final int ind = getRepositeryModelIndex(reposInf);
294    //
295    // if (ind != -1)
296    // return table.convertRowIndexToView(ind);
297    //
298    // return ind;
299    // }
300
301    RepositoryInfo getSelectedRepository()
302    {
303        int index;
304
305        index = table.getSelectedRow();
306        if (index == -1)
307            return null;
308
309        index = table.convertRowIndexToModel(index);
310        if (index == -1)
311            return null;
312
313        return repositories.get(index);
314    }
315
316    boolean addRepository()
317    {
318        final RepositoryInfo reposInf = new RepositoryInfo("name", "http://");
319
320        if (!new EditRepositoryDialog("Add a new repository", reposInf).isCanceled())
321        {
322            // add new repository entry
323            repositories.add(reposInf);
324            // get index
325            final int ind = getRepositeryModelIndex(reposInf);
326            // notify data changed
327            tableModel.fireTableRowsInserted(ind, ind);
328
329            return true;
330        }
331
332        return false;
333    }
334
335    boolean editRepository(final RepositoryInfo reposInf)
336    {
337        final int ind = getRepositeryModelIndex(reposInf);
338
339        if (!new EditRepositoryDialog("Edit repository", reposInf).isCanceled())
340        {
341            try
342            {
343                // notify data changed
344                tableModel.fireTableRowsUpdated(ind, ind);
345            }
346            catch (Exception e)
347            {
348                // ignore possible exception here
349            }
350
351            return true;
352        }
353
354        return false;
355    }
356
357    boolean removeRepository(final RepositoryInfo reposInf)
358    {
359        final int ind = getRepositeryModelIndex(reposInf);
360
361        if (repositories.remove(reposInf))
362        {
363            // notify data changed
364            tableModel.fireTableRowsDeleted(ind, ind);
365
366            return true;
367        }
368
369        return false;
370    }
371
372    private void udpateButtonsState()
373    {
374        final RepositoryInfo selectedRepos = getSelectedRepository();
375        final boolean enabled = (selectedRepos != null) && !selectedRepos.isDefault();
376
377        editButton.setEnabled(enabled);
378        removeButton.setEnabled(enabled);
379    }
380
381    @Override
382    public void valueChanged(ListSelectionEvent e)
383    {
384        udpateButtonsState();
385    }
386
387}