James Moger
2011-10-21 b75734f0600c333d70a3659af82be54caf3cfd3e
commit | author | age
19c634 1 /*
JM 2  * Copyright 2011 gitblit.com.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.gitblit.client;
17
18 import java.awt.BorderLayout;
841651 19 import java.awt.Color;
19c634 20 import java.awt.Component;
841651 21 import java.awt.Desktop;
44f2da 22 import java.awt.FlowLayout;
841651 23 import java.awt.Insets;
JM 24 import java.awt.event.ActionEvent;
25 import java.awt.event.ActionListener;
e15f95 26 import java.awt.event.KeyAdapter;
JM 27 import java.awt.event.KeyEvent;
f14f76 28 import java.awt.event.MouseAdapter;
JM 29 import java.awt.event.MouseEvent;
19c634 30 import java.io.IOException;
841651 31 import java.net.URI;
JM 32 import java.text.MessageFormat;
33 import java.util.ArrayList;
34 import java.util.List;
19c634 35
841651 36 import javax.swing.JButton;
JM 37 import javax.swing.JLabel;
da0269 38 import javax.swing.JOptionPane;
19c634 39 import javax.swing.JPanel;
JM 40 import javax.swing.JScrollPane;
41 import javax.swing.JTabbedPane;
42 import javax.swing.JTable;
841651 43 import javax.swing.JTextField;
JM 44 import javax.swing.RowFilter;
45 import javax.swing.SwingConstants;
46 import javax.swing.event.ListSelectionEvent;
47 import javax.swing.event.ListSelectionListener;
48 import javax.swing.table.DefaultTableCellRenderer;
19c634 49 import javax.swing.table.TableCellRenderer;
841651 50 import javax.swing.table.TableRowSorter;
19c634 51
da0269 52 import com.gitblit.Constants.RpcRequest;
841651 53 import com.gitblit.client.ClosableTabComponent.CloseTabListener;
19c634 54 import com.gitblit.models.RepositoryModel;
b75734 55 import com.gitblit.models.SettingModel;
841651 56 import com.gitblit.models.UserModel;
JM 57 import com.gitblit.utils.StringUtils;
19c634 58
841651 59 /**
JM 60  * GitblitPanel performs the login, all business logic, and contains all widgets
61  * to represent the state of a repository for the given account credentials.
62  * 
63  * @author James Moger
64  * 
65  */
66 public class GitblitPanel extends JPanel implements CloseTabListener {
19c634 67
JM 68     private static final long serialVersionUID = 1L;
69
841651 70     private final int margin = 5;
19c634 71
841651 72     private final Insets insets = new Insets(margin, margin, margin, margin);
JM 73
15a51d 74     private GitblitModel gitblit;
841651 75
JM 76     private JTabbedPane tabs;
19c634 77
JM 78     private JTable repositoriesTable;
841651 79
JM 80     private RepositoriesModel repositoriesModel;
81
4b430b 82     private JTable usersTable;
JM 83
84     private UsersModel usersModel;
841651 85
ee25c8 86     private JTable settingsTable;
JM 87
88     private SettingsModel settingsModel;
89
841651 90     private JButton createRepository;
JM 91
92     private JButton delRepository;
93
94     private NameRenderer nameRenderer;
95
b7f591 96     private IndicatorsRenderer typeRenderer;
841651 97
JM 98     private DefaultTableCellRenderer ownerRenderer;
99
100     private DefaultTableCellRenderer sizeRenderer;
101
4b430b 102     private TableRowSorter<RepositoriesModel> defaultRepositoriesSorter;
JM 103
104     private TableRowSorter<UsersModel> defaultUsersSorter;
105
ee25c8 106     private TableRowSorter<SettingsModel> defaultSettingsSorter;
JM 107
4b430b 108     private JButton editRepository;
841651 109
JM 110     public GitblitPanel(GitblitRegistration reg) {
111         this(reg.url, reg.account, reg.password);
112     }
19c634 113
JM 114     public GitblitPanel(String url, String account, char[] password) {
15a51d 115         this.gitblit = new GitblitModel(url, account, password);
19c634 116
ee25c8 117         tabs = new JTabbedPane(JTabbedPane.BOTTOM);
JM 118         tabs.addTab(Translation.get("gb.repositories"), createRepositoriesPanel());
119         tabs.addTab(Translation.get("gb.users"), createUsersPanel());
120         tabs.addTab(Translation.get("gb.settings"), createSettingsPanel());
121
122         setLayout(new BorderLayout());
123         add(tabs, BorderLayout.CENTER);
124     }
125
126     private JPanel createRepositoriesPanel() {
b7f591 127         final JButton browseRepository = new JButton(Translation.get("gb.browse"));
841651 128         browseRepository.setEnabled(false);
JM 129         browseRepository.addActionListener(new ActionListener() {
130             public void actionPerformed(ActionEvent e) {
131                 RepositoryModel model = getSelectedRepositories().get(0);
15a51d 132                 String u = MessageFormat.format("{0}/summary/{1}", gitblit.url,
841651 133                         StringUtils.encodeURL(model.name));
JM 134                 try {
135                     Desktop.getDesktop().browse(new URI(u));
136                 } catch (Exception x) {
137                     x.printStackTrace();
138                 }
139             }
140         });
19c634 141
b7f591 142         JButton refreshRepositories = new JButton(Translation.get("gb.refresh"));
da0269 143         refreshRepositories.addActionListener(new ActionListener() {
JM 144             public void actionPerformed(ActionEvent e) {
15a51d 145                 refreshRepositories();
da0269 146             }
JM 147         });
148
b7f591 149         createRepository = new JButton(Translation.get("gb.create"));
841651 150         createRepository.addActionListener(new ActionListener() {
JM 151             public void actionPerformed(ActionEvent e) {
da0269 152                 createRepository();
841651 153             }
JM 154         });
155
4b430b 156         editRepository = new JButton(Translation.get("gb.edit"));
841651 157         editRepository.setEnabled(false);
JM 158         editRepository.addActionListener(new ActionListener() {
159             public void actionPerformed(ActionEvent e) {
da0269 160                 editRepository(getSelectedRepositories().get(0));
841651 161             }
JM 162         });
163
b7f591 164         delRepository = new JButton(Translation.get("gb.delete"));
841651 165         delRepository.setEnabled(false);
JM 166         delRepository.addActionListener(new ActionListener() {
167             public void actionPerformed(ActionEvent e) {
da0269 168                 deleteRepositories(getSelectedRepositories());
841651 169             }
JM 170         });
171
da0269 172         nameRenderer = new NameRenderer();
b7f591 173         typeRenderer = new IndicatorsRenderer();
841651 174
JM 175         sizeRenderer = new DefaultTableCellRenderer();
176         sizeRenderer.setHorizontalAlignment(SwingConstants.RIGHT);
177         sizeRenderer.setForeground(new Color(0, 0x80, 0));
178
179         ownerRenderer = new DefaultTableCellRenderer();
180         ownerRenderer.setForeground(Color.gray);
181         ownerRenderer.setHorizontalAlignment(SwingConstants.CENTER);
182
183         repositoriesModel = new RepositoriesModel();
4b430b 184         defaultRepositoriesSorter = new TableRowSorter<RepositoriesModel>(repositoriesModel);
JM 185         repositoriesTable = Utils.newTable(repositoriesModel);
186         repositoriesTable.setRowHeight(nameRenderer.getFont().getSize() + 8);
187         repositoriesTable.setRowSorter(defaultRepositoriesSorter);
841651 188         repositoriesTable.getRowSorter().toggleSortOrder(RepositoriesModel.Columns.Name.ordinal());
JM 189
ee25c8 190         setRepositoryRenderer(RepositoriesModel.Columns.Name, nameRenderer, -1);
JM 191         setRepositoryRenderer(RepositoriesModel.Columns.Indicators, typeRenderer, 100);
192         setRepositoryRenderer(RepositoriesModel.Columns.Owner, ownerRenderer, -1);
193         setRepositoryRenderer(RepositoriesModel.Columns.Size, sizeRenderer, 60);
841651 194
JM 195         repositoriesTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
196             @Override
197             public void valueChanged(ListSelectionEvent e) {
198                 if (e.getValueIsAdjusting()) {
199                     return;
200                 }
201                 boolean singleSelection = repositoriesTable.getSelectedRowCount() == 1;
202                 boolean selected = repositoriesTable.getSelectedRow() > -1;
203                 browseRepository.setEnabled(singleSelection);
204                 delRepository.setEnabled(selected);
205                 if (selected) {
206                     int viewRow = repositoriesTable.getSelectedRow();
207                     int modelRow = repositoriesTable.convertRowIndexToModel(viewRow);
208                     RepositoryModel model = ((RepositoriesModel) repositoriesTable.getModel()).list
209                             .get(modelRow);
210                     editRepository.setEnabled(singleSelection
15a51d 211                             && (gitblit.allowAdmin() || gitblit.isOwner(model)));
841651 212                 } else {
JM 213                     editRepository.setEnabled(false);
214                 }
215             }
216         });
5ae0b7 217
f14f76 218         repositoriesTable.addMouseListener(new MouseAdapter() {
JM 219             public void mouseClicked(MouseEvent e) {
5ae0b7 220                 if (e.getClickCount() == 2 && gitblit.allowAdmin()) {
f14f76 221                     editRepository(getSelectedRepositories().get(0));
JM 222                 }
223             }
224         });
841651 225
JM 226         final JTextField repositoryFilter = new JTextField();
227         repositoryFilter.addActionListener(new ActionListener() {
228             public void actionPerformed(ActionEvent e) {
229                 filterRepositories(repositoryFilter.getText());
230             }
231         });
e15f95 232         repositoryFilter.addKeyListener(new KeyAdapter() {
JM 233             public void keyReleased(KeyEvent e) {
234                 filterRepositories(repositoryFilter.getText());
235             }
236         });
841651 237
e15f95 238         JPanel repositoryFilterPanel = new JPanel(new BorderLayout(margin, margin));
JM 239         repositoryFilterPanel.add(new JLabel(Translation.get("gb.filter")), BorderLayout.WEST);
240         repositoryFilterPanel.add(repositoryFilter, BorderLayout.CENTER);
841651 241
e15f95 242         JPanel repositoryTablePanel = new JPanel(new BorderLayout(margin, margin));
JM 243         repositoryTablePanel.add(repositoryFilterPanel, BorderLayout.NORTH);
244         repositoryTablePanel.add(new JScrollPane(repositoriesTable), BorderLayout.CENTER);
841651 245
44f2da 246         JPanel repositoryControls = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));
15a51d 247         repositoryControls.add(refreshRepositories);
841651 248         repositoryControls.add(browseRepository);
JM 249         repositoryControls.add(createRepository);
250         repositoryControls.add(editRepository);
251         repositoryControls.add(delRepository);
252
44f2da 253         JPanel repositoriesPanel = new JPanel(new BorderLayout(margin, margin)) {
JM 254
255             private static final long serialVersionUID = 1L;
256
257             public Insets getInsets() {
258                 return insets;
259             }
260         };
ee25c8 261         repositoriesPanel.add(new HeaderPanel(Translation.get("gb.repositories"),
JM 262                 "gitweb-favicon.png"), BorderLayout.NORTH);
e15f95 263         repositoriesPanel.add(repositoryTablePanel, BorderLayout.CENTER);
841651 264         repositoriesPanel.add(repositoryControls, BorderLayout.SOUTH);
JM 265
ee25c8 266         return repositoriesPanel;
JM 267     }
268
269     private void setRepositoryRenderer(RepositoriesModel.Columns col, TableCellRenderer renderer,
270             int maxWidth) {
271         String name = repositoriesTable.getColumnName(col.ordinal());
272         repositoriesTable.getColumn(name).setCellRenderer(renderer);
273         if (maxWidth > 0) {
274             repositoriesTable.getColumn(name).setMinWidth(maxWidth);
275             repositoriesTable.getColumn(name).setMaxWidth(maxWidth);
276         }
277     }
278
279     private JPanel createUsersPanel() {
b7f591 280         JButton refreshUsers = new JButton(Translation.get("gb.refresh"));
da0269 281         refreshUsers.addActionListener(new ActionListener() {
JM 282             public void actionPerformed(ActionEvent e) {
15a51d 283                 refreshUsers();
da0269 284             }
JM 285         });
286
b7f591 287         JButton createUser = new JButton(Translation.get("gb.create"));
841651 288         createUser.addActionListener(new ActionListener() {
JM 289             public void actionPerformed(ActionEvent e) {
da0269 290                 createUser();
841651 291             }
JM 292         });
293
b7f591 294         final JButton editUser = new JButton(Translation.get("gb.edit"));
841651 295         editUser.setEnabled(false);
JM 296         editUser.addActionListener(new ActionListener() {
297             public void actionPerformed(ActionEvent e) {
da0269 298                 editUser(getSelectedUsers().get(0));
841651 299             }
JM 300         });
301
b7f591 302         final JButton delUser = new JButton(Translation.get("gb.delete"));
841651 303         delUser.setEnabled(false);
JM 304         delUser.addActionListener(new ActionListener() {
305             public void actionPerformed(ActionEvent e) {
da0269 306                 deleteUsers(getSelectedUsers());
841651 307             }
JM 308         });
309
4b430b 310         usersModel = new UsersModel();
JM 311         defaultUsersSorter = new TableRowSorter<UsersModel>(usersModel);
312         usersTable = Utils.newTable(usersModel);
313         String name = usersTable.getColumnName(UsersModel.Columns.Name.ordinal());
314         usersTable.setRowHeight(nameRenderer.getFont().getSize() + 8);
315         usersTable.getColumn(name).setCellRenderer(nameRenderer);
316         usersTable.setRowSorter(defaultUsersSorter);
317         usersTable.getRowSorter().toggleSortOrder(UsersModel.Columns.Name.ordinal());
318         usersTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
841651 319
JM 320             @Override
321             public void valueChanged(ListSelectionEvent e) {
322                 if (e.getValueIsAdjusting()) {
323                     return;
324                 }
4b430b 325                 boolean selected = usersTable.getSelectedRow() > -1;
JM 326                 boolean singleSelection = usersTable.getSelectedRows().length == 1;
841651 327                 editUser.setEnabled(singleSelection && selected);
JM 328                 delUser.setEnabled(selected);
f14f76 329             }
JM 330         });
5ae0b7 331
f14f76 332         usersTable.addMouseListener(new MouseAdapter() {
JM 333             public void mouseClicked(MouseEvent e) {
334                 if (e.getClickCount() == 2) {
335                     editUser(getSelectedUsers().get(0));
336                 }
841651 337             }
JM 338         });
339
e15f95 340         final JTextField userFilter = new JTextField();
JM 341         userFilter.addActionListener(new ActionListener() {
342             public void actionPerformed(ActionEvent e) {
343                 filterUsers(userFilter.getText());
344             }
345         });
346         userFilter.addKeyListener(new KeyAdapter() {
347             public void keyReleased(KeyEvent e) {
348                 filterUsers(userFilter.getText());
349             }
350         });
351
352         JPanel userFilterPanel = new JPanel(new BorderLayout(margin, margin));
353         userFilterPanel.add(new JLabel(Translation.get("gb.filter")), BorderLayout.WEST);
354         userFilterPanel.add(userFilter, BorderLayout.CENTER);
355
356         JPanel userTablePanel = new JPanel(new BorderLayout(margin, margin));
357         userTablePanel.add(userFilterPanel, BorderLayout.NORTH);
358         userTablePanel.add(new JScrollPane(usersTable), BorderLayout.CENTER);
359
44f2da 360         JPanel userControls = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));
da0269 361         userControls.add(refreshUsers);
841651 362         userControls.add(createUser);
JM 363         userControls.add(editUser);
364         userControls.add(delUser);
365
44f2da 366         JPanel usersPanel = new JPanel(new BorderLayout(margin, margin)) {
JM 367
368             private static final long serialVersionUID = 1L;
369
370             public Insets getInsets() {
371                 return insets;
372             }
373         };
ee25c8 374         usersPanel.add(new HeaderPanel(Translation.get("gb.users"), "user_16x16.png"),
JM 375                 BorderLayout.NORTH);
e15f95 376         usersPanel.add(userTablePanel, BorderLayout.CENTER);
841651 377         usersPanel.add(userControls, BorderLayout.SOUTH);
JM 378
ee25c8 379         return usersPanel;
841651 380     }
JM 381
ee25c8 382     private JPanel createSettingsPanel() {
b75734 383         final SettingPanel settingPanel = new SettingPanel();
ee25c8 384         settingsModel = new SettingsModel();
JM 385         defaultSettingsSorter = new TableRowSorter<SettingsModel>(settingsModel);
386         settingsTable = Utils.newTable(settingsModel);
b75734 387         settingsTable.setDefaultRenderer(SettingModel.class, new SettingCellRenderer());
ee25c8 388         String name = settingsTable.getColumnName(UsersModel.Columns.Name.ordinal());
JM 389         settingsTable.setRowHeight(nameRenderer.getFont().getSize() + 8);
390         settingsTable.getColumn(name).setCellRenderer(nameRenderer);
391         settingsTable.setRowSorter(defaultSettingsSorter);
392         settingsTable.getRowSorter().toggleSortOrder(SettingsModel.Columns.Name.ordinal());
393         settingsTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
394
395             @Override
396             public void valueChanged(ListSelectionEvent e) {
397                 if (e.getValueIsAdjusting()) {
398                     return;
399                 }
400                 boolean selected = settingsTable.getSelectedRow() > -1;
401                 boolean singleSelection = settingsTable.getSelectedRows().length == 1;
402                 // TODO enable/disable setting buttons
b75734 403                 if (singleSelection) {
JM 404                     int viewRow = settingsTable.getSelectedRow();
405                     int modelRow = settingsTable.convertRowIndexToModel(viewRow);
406                     SettingModel setting = settingsModel.get(modelRow);
407                     settingPanel.setSetting(setting);
408                 } else {
409                     settingPanel.clear();
410                 }
ee25c8 411             }
JM 412         });
413
414         final JTextField settingFilter = new JTextField();
415         settingFilter.addActionListener(new ActionListener() {
416             public void actionPerformed(ActionEvent e) {
417                 filterSettings(settingFilter.getText());
418             }
419         });
420         settingFilter.addKeyListener(new KeyAdapter() {
421             public void keyReleased(KeyEvent e) {
422                 filterSettings(settingFilter.getText());
423             }
424         });
425
426         JPanel settingFilterPanel = new JPanel(new BorderLayout(margin, margin));
427         settingFilterPanel.add(new JLabel(Translation.get("gb.filter")), BorderLayout.WEST);
428         settingFilterPanel.add(settingFilter, BorderLayout.CENTER);
429
430         JPanel settingsTablePanel = new JPanel(new BorderLayout(margin, margin));
431         settingsTablePanel.add(settingFilterPanel, BorderLayout.NORTH);
432         settingsTablePanel.add(new JScrollPane(settingsTable), BorderLayout.CENTER);
b75734 433         settingsTablePanel.add(settingPanel, BorderLayout.SOUTH);
ee25c8 434
JM 435         JPanel settingsControls = new JPanel(new FlowLayout(FlowLayout.CENTER, 5, 0));
436         // TODO update setting?
437
438         JPanel settingsPanel = new JPanel(new BorderLayout(margin, margin)) {
439
440             private static final long serialVersionUID = 1L;
441
442             public Insets getInsets() {
443                 return insets;
444             }
445         };
446         settingsPanel.add(new HeaderPanel(Translation.get("gb.settings"), "settings_16x16.png"),
447                 BorderLayout.NORTH);
448         settingsPanel.add(settingsTablePanel, BorderLayout.CENTER);
449         settingsPanel.add(settingsControls, BorderLayout.SOUTH);
450
451         return settingsPanel;
15a51d 452     }
841651 453
15a51d 454     public void login() throws IOException {
JM 455         gitblit.login();
456
457         updateRepositoriesTable();
458         Utils.packColumns(repositoriesTable, 2);
459
460         if (gitblit.allowAdmin()) {
461             updateUsersTable();
ee25c8 462             updateSettingsTable();
15a51d 463         } else {
841651 464             // user does not have administrator privileges
JM 465             // hide admin repository buttons
466             createRepository.setVisible(false);
4b430b 467             editRepository.setVisible(false);
841651 468             delRepository.setVisible(false);
JM 469
4b430b 470             while (tabs.getTabCount() > 1) {
JM 471                 // remove admin tabs
472                 tabs.removeTabAt(1);
473             }
841651 474         }
19c634 475     }
JM 476
15a51d 477     private void updateRepositoriesTable() {
841651 478         repositoriesModel.list.clear();
15a51d 479         repositoriesModel.list.addAll(gitblit.getRepositories());
841651 480         repositoriesModel.fireTableDataChanged();
JM 481     }
482
15a51d 483     private void updateUsersTable() {
4b430b 484         usersModel.list.clear();
JM 485         usersModel.list.addAll(gitblit.getUsers());
486         usersModel.fireTableDataChanged();
ee25c8 487     }
JM 488
489     private void updateSettingsTable() {
490         settingsModel.setSettings(gitblit.getSettings());
491         settingsModel.fireTableDataChanged();
841651 492     }
JM 493
494     private void filterRepositories(final String fragment) {
495         if (StringUtils.isEmpty(fragment)) {
4b430b 496             repositoriesTable.setRowSorter(defaultRepositoriesSorter);
841651 497             return;
JM 498         }
499         RowFilter<RepositoriesModel, Object> containsFilter = new RowFilter<RepositoriesModel, Object>() {
500             public boolean include(Entry<? extends RepositoriesModel, ? extends Object> entry) {
501                 for (int i = entry.getValueCount() - 1; i >= 0; i--) {
502                     if (entry.getStringValue(i).toLowerCase().contains(fragment.toLowerCase())) {
503                         return true;
504                     }
505                 }
506                 return false;
507             }
508         };
e15f95 509         TableRowSorter<RepositoriesModel> sorter = new TableRowSorter<RepositoriesModel>(
JM 510                 repositoriesModel);
841651 511         sorter.setRowFilter(containsFilter);
JM 512         repositoriesTable.setRowSorter(sorter);
513     }
514
e15f95 515     private void filterUsers(final String fragment) {
JM 516         if (StringUtils.isEmpty(fragment)) {
517             usersTable.setRowSorter(defaultUsersSorter);
518             return;
519         }
520         RowFilter<UsersModel, Object> containsFilter = new RowFilter<UsersModel, Object>() {
521             public boolean include(Entry<? extends UsersModel, ? extends Object> entry) {
522                 for (int i = entry.getValueCount() - 1; i >= 0; i--) {
523                     if (entry.getStringValue(i).toLowerCase().contains(fragment.toLowerCase())) {
524                         return true;
525                     }
526                 }
527                 return false;
528             }
529         };
530         TableRowSorter<UsersModel> sorter = new TableRowSorter<UsersModel>(usersModel);
531         sorter.setRowFilter(containsFilter);
532         usersTable.setRowSorter(sorter);
ee25c8 533     }
JM 534
535     private void filterSettings(final String fragment) {
536         if (StringUtils.isEmpty(fragment)) {
537             settingsTable.setRowSorter(defaultSettingsSorter);
538             return;
539         }
540         RowFilter<SettingsModel, Object> containsFilter = new RowFilter<SettingsModel, Object>() {
541             public boolean include(Entry<? extends SettingsModel, ? extends Object> entry) {
542                 for (int i = entry.getValueCount() - 1; i >= 0; i--) {
543                     if (entry.getStringValue(i).toLowerCase().contains(fragment.toLowerCase())) {
544                         return true;
545                     }
546                 }
547                 return false;
548             }
549         };
550         TableRowSorter<SettingsModel> sorter = new TableRowSorter<SettingsModel>(settingsModel);
551         sorter.setRowFilter(containsFilter);
552         settingsTable.setRowSorter(sorter);
e15f95 553     }
JM 554
841651 555     private List<RepositoryModel> getSelectedRepositories() {
JM 556         List<RepositoryModel> repositories = new ArrayList<RepositoryModel>();
557         for (int viewRow : repositoriesTable.getSelectedRows()) {
558             int modelRow = repositoriesTable.convertRowIndexToModel(viewRow);
4b430b 559             RepositoryModel model = repositoriesModel.list.get(modelRow);
841651 560             repositories.add(model);
JM 561         }
562         return repositories;
563     }
564
565     private List<UserModel> getSelectedUsers() {
566         List<UserModel> users = new ArrayList<UserModel>();
4b430b 567         for (int viewRow : usersTable.getSelectedRows()) {
JM 568             int modelRow = usersTable.convertRowIndexToModel(viewRow);
569             UserModel model = usersModel.list.get(modelRow);
841651 570             users.add(model);
JM 571         }
572         return users;
19c634 573     }
JM 574
841651 575     @Override
JM 576     public Insets getInsets() {
577         return insets;
578     }
579
580     @Override
581     public void closeTab(Component c) {
15a51d 582         gitblit = null;
JM 583     }
584
5ae0b7 585     protected void refreshRepositories() {
15a51d 586         GitblitWorker worker = new GitblitWorker(GitblitPanel.this, RpcRequest.LIST_REPOSITORIES) {
JM 587             @Override
588             protected Boolean doRequest() throws IOException {
589                 gitblit.refreshRepositories();
590                 return true;
591             }
592
593             @Override
594             protected void onSuccess() {
595                 updateRepositoriesTable();
596             }
597         };
598         worker.execute();
841651 599     }
da0269 600
JM 601     /**
602      * Displays the create repository dialog and fires a SwingWorker to update
603      * the server, if appropriate.
604      * 
605      */
606     protected void createRepository() {
bcc616 607         EditRepositoryDialog dialog = new EditRepositoryDialog();
f14f76 608         dialog.setLocationRelativeTo(GitblitPanel.this);
15a51d 609         dialog.setUsers(null, gitblit.getUsernames(), null);
JM 610         dialog.setRepositories(gitblit.getRepositories());
da0269 611         dialog.setVisible(true);
JM 612         final RepositoryModel newRepository = dialog.getRepository();
bcc616 613         final List<String> permittedUsers = dialog.getPermittedUsers();
da0269 614         if (newRepository == null) {
JM 615             return;
616         }
617
15a51d 618         GitblitWorker worker = new GitblitWorker(this, RpcRequest.CREATE_REPOSITORY) {
da0269 619
JM 620             @Override
15a51d 621             protected Boolean doRequest() throws IOException {
JM 622                 boolean success = gitblit.createRepository(newRepository, permittedUsers);
623                 if (success) {
624                     gitblit.refreshRepositories();
625                     if (permittedUsers.size() > 0) {
626                         gitblit.refreshUsers();
627                     }
bcc616 628                 }
JM 629                 return success;
da0269 630             }
JM 631
632             @Override
15a51d 633             protected void onSuccess() {
JM 634                 updateRepositoriesTable();
635                 updateUsersTable();
636             }
637
638             @Override
639             protected void onFailure() {
640                 showFailure("Failed to execute request \"{0}\" for repository \"{1}\".",
641                         getRequestType(), newRepository.name);
da0269 642             }
JM 643         };
644         worker.execute();
645     }
646
647     /**
648      * Displays the edit repository dialog and fires a SwingWorker to update the
649      * server, if appropriate.
650      * 
651      * @param repository
652      */
653     protected void editRepository(final RepositoryModel repository) {
bcc616 654         EditRepositoryDialog dialog = new EditRepositoryDialog(repository);
f14f76 655         dialog.setLocationRelativeTo(GitblitPanel.this);
15a51d 656         List<String> usernames = gitblit.getUsernames();
JM 657         List<String> members = gitblit.getPermittedUsernames(repository);
bcc616 658         dialog.setUsers(repository.owner, usernames, members);
15a51d 659         dialog.setFederationSets(gitblit.getFederationSets(), repository.federationSets);
da0269 660         dialog.setVisible(true);
JM 661         final RepositoryModel revisedRepository = dialog.getRepository();
bcc616 662         final List<String> permittedUsers = dialog.getPermittedUsers();
da0269 663         if (revisedRepository == null) {
JM 664             return;
665         }
666
15a51d 667         GitblitWorker worker = new GitblitWorker(this, RpcRequest.EDIT_REPOSITORY) {
da0269 668
JM 669             @Override
15a51d 670             protected Boolean doRequest() throws IOException {
JM 671                 boolean success = gitblit.updateRepository(repository.name, revisedRepository,
672                         permittedUsers);
673                 if (success) {
674                     gitblit.refreshRepositories();
675                     gitblit.refreshUsers();
676                 }
bcc616 677                 return success;
da0269 678             }
JM 679
680             @Override
15a51d 681             protected void onSuccess() {
JM 682                 updateRepositoriesTable();
683                 updateUsersTable();
684             }
685
686             @Override
687             protected void onFailure() {
688                 showFailure("Failed to execute request \"{0}\" for repository \"{1}\".",
689                         getRequestType(), repository.name);
da0269 690             }
JM 691         };
692         worker.execute();
693     }
694
695     protected void deleteRepositories(final List<RepositoryModel> repositories) {
696         if (repositories == null || repositories.size() == 0) {
697             return;
698         }
699         StringBuilder message = new StringBuilder("Delete the following repositories?\n\n");
700         for (RepositoryModel repository : repositories) {
701             message.append(repository.name).append("\n");
702         }
703         int result = JOptionPane.showConfirmDialog(GitblitPanel.this, message.toString(),
704                 "Delete Repositories?", JOptionPane.YES_NO_OPTION);
705         if (result == JOptionPane.YES_OPTION) {
15a51d 706             GitblitWorker worker = new GitblitWorker(this, RpcRequest.DELETE_REPOSITORY) {
da0269 707                 @Override
15a51d 708                 protected Boolean doRequest() throws IOException {
da0269 709                     boolean success = true;
JM 710                     for (RepositoryModel repository : repositories) {
15a51d 711                         success &= gitblit.deleteRepository(repository);
JM 712                     }
713                     if (success) {
ee25c8 714                         gitblit.refreshRepositories();
15a51d 715                         gitblit.refreshUsers();
da0269 716                     }
JM 717                     return success;
718                 }
719
720                 @Override
15a51d 721                 protected void onSuccess() {
JM 722                     updateRepositoriesTable();
723                     updateUsersTable();
724                 }
725
726                 @Override
727                 protected void onFailure() {
728                     showFailure("Failed to delete specified repositories!");
da0269 729                 }
JM 730             };
731             worker.execute();
732         }
15a51d 733     }
JM 734
735     protected void refreshUsers() {
736         GitblitWorker worker = new GitblitWorker(GitblitPanel.this, RpcRequest.LIST_USERS) {
737             @Override
738             protected Boolean doRequest() throws IOException {
739                 gitblit.refreshUsers();
740                 return true;
741             }
742
743             @Override
744             protected void onSuccess() {
745                 updateUsersTable();
746             }
747         };
748         worker.execute();
da0269 749     }
JM 750
751     /**
752      * Displays the create user dialog and fires a SwingWorker to update the
753      * server, if appropriate.
754      * 
755      */
756     protected void createUser() {
15a51d 757         EditUserDialog dialog = new EditUserDialog(gitblit.getSettings());
f14f76 758         dialog.setLocationRelativeTo(GitblitPanel.this);
15a51d 759         dialog.setUsers(gitblit.getUsers());
JM 760         dialog.setRepositories(gitblit.getRepositories(), null);
da0269 761         dialog.setVisible(true);
JM 762         final UserModel newUser = dialog.getUser();
763         if (newUser == null) {
764             return;
765         }
766
15a51d 767         GitblitWorker worker = new GitblitWorker(this, RpcRequest.CREATE_USER) {
da0269 768
JM 769             @Override
15a51d 770             protected Boolean doRequest() throws IOException {
JM 771                 boolean success = gitblit.createUser(newUser);
772                 if (success) {
773                     gitblit.refreshUsers();
774                 }
775                 return success;
da0269 776             }
JM 777
778             @Override
15a51d 779             protected void onSuccess() {
JM 780                 updateUsersTable();
781             }
782
783             @Override
784             protected void onFailure() {
785                 showFailure("Failed to execute request \"{0}\" for user \"{1}\".",
786                         getRequestType(), newUser.username);
da0269 787             }
JM 788         };
789         worker.execute();
790     }
791
792     /**
793      * Displays the edit user dialog and fires a SwingWorker to update the
794      * server, if appropriate.
795      * 
796      * @param user
797      */
798     protected void editUser(final UserModel user) {
15a51d 799         EditUserDialog dialog = new EditUserDialog(user, gitblit.getSettings());
f14f76 800         dialog.setLocationRelativeTo(GitblitPanel.this);
15a51d 801         dialog.setRepositories(gitblit.getRepositories(), new ArrayList<String>(user.repositories));
da0269 802         dialog.setVisible(true);
JM 803         final UserModel revisedUser = dialog.getUser();
804         if (revisedUser == null) {
805             return;
806         }
807
15a51d 808         GitblitWorker worker = new GitblitWorker(this, RpcRequest.EDIT_USER) {
da0269 809             @Override
15a51d 810             protected Boolean doRequest() throws IOException {
JM 811                 boolean success = gitblit.updateUser(user.username, revisedUser);
812                 if (success) {
813                     gitblit.refreshUsers();
814                 }
815                 return success;
da0269 816             }
JM 817
818             @Override
15a51d 819             protected void onSuccess() {
JM 820                 updateUsersTable();
821             }
822
823             @Override
824             protected void onFailure() {
825                 showFailure("Failed to execute request \"{0}\" for user \"{1}\".",
826                         getRequestType(), user.username);
da0269 827             }
JM 828         };
829         worker.execute();
830     }
831
832     protected void deleteUsers(final List<UserModel> users) {
833         if (users == null || users.size() == 0) {
834             return;
835         }
836         StringBuilder message = new StringBuilder("Delete the following users?\n\n");
837         for (UserModel user : users) {
838             message.append(user.username).append("\n");
839         }
840         int result = JOptionPane.showConfirmDialog(GitblitPanel.this, message.toString(),
841                 "Delete Users?", JOptionPane.YES_NO_OPTION);
842         if (result == JOptionPane.YES_OPTION) {
15a51d 843             GitblitWorker worker = new GitblitWorker(this, RpcRequest.DELETE_USER) {
da0269 844                 @Override
15a51d 845                 protected Boolean doRequest() throws IOException {
da0269 846                     boolean success = true;
JM 847                     for (UserModel user : users) {
15a51d 848                         success &= gitblit.deleteUser(user);
JM 849                     }
850                     if (success) {
851                         gitblit.refreshUsers();
da0269 852                     }
JM 853                     return success;
854                 }
855
856                 @Override
15a51d 857                 protected void onSuccess() {
JM 858                     updateUsersTable();
859                 }
860
861                 @Override
862                 protected void onFailure() {
863                     showFailure("Failed to delete specified users!");
da0269 864                 }
JM 865             };
866             worker.execute();
867         }
868     }
15a51d 869 }