/[svn]/jsampler/trunk/src/org/jsampler/view/fantasia/MainFrame.java
ViewVC logotype

Diff of /jsampler/trunk/src/org/jsampler/view/fantasia/MainFrame.java

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1308 by iliev, Tue Aug 28 17:00:19 2007 UTC revision 1729 by iliev, Tue Apr 29 22:22:40 2008 UTC
# Line 1  Line 1 
1  /*  /*
2   *   JSampler - a java front-end for LinuxSampler   *   JSampler - a java front-end for LinuxSampler
3   *   *
4   *   Copyright (C) 2005-2007 Grigor Iliev <grigor@grigoriliev.com>   *   Copyright (C) 2005-2008 Grigor Iliev <grigor@grigoriliev.com>
5   *   *
6   *   This file is part of JSampler.   *   This file is part of JSampler.
7   *   *
# Line 50  import javax.swing.BorderFactory; Line 50  import javax.swing.BorderFactory;
50  import javax.swing.Box;  import javax.swing.Box;
51  import javax.swing.BoxLayout;  import javax.swing.BoxLayout;
52  import javax.swing.JCheckBoxMenuItem;  import javax.swing.JCheckBoxMenuItem;
53    import javax.swing.JComponent;
54  import javax.swing.JDialog;  import javax.swing.JDialog;
55  import javax.swing.JFileChooser;  import javax.swing.JFileChooser;
56  import javax.swing.JFrame;  import javax.swing.JFrame;
# Line 70  import net.sf.juife.TitleBar; Line 71  import net.sf.juife.TitleBar;
71  import org.jsampler.CC;  import org.jsampler.CC;
72  import org.jsampler.HF;  import org.jsampler.HF;
73  import org.jsampler.LSConsoleModel;  import org.jsampler.LSConsoleModel;
74    import org.jsampler.Server;
75    
76  import org.jsampler.view.JSChannel;  import org.jsampler.view.JSChannel;
77  import org.jsampler.view.JSChannelsPane;  import org.jsampler.view.JSChannelsPane;
78  import org.jsampler.view.JSMainFrame;  import org.jsampler.view.JSMainFrame;
79  import org.jsampler.view.LscpFileFilter;  import org.jsampler.view.LscpFileFilter;
80    
81    import org.jsampler.view.std.JSConnectDlg;
82    import org.jsampler.view.std.JSDetailedErrorDlg;
83    import org.jsampler.view.std.JSQuitDlg;
84  import org.jsampler.view.std.JSamplerHomeChooser;  import org.jsampler.view.std.JSamplerHomeChooser;
85    
86  import static org.jsampler.view.fantasia.A4n.a4n;  import static org.jsampler.view.fantasia.A4n.a4n;
# Line 89  import static org.jsampler.view.std.StdP Line 94  import static org.jsampler.view.std.StdP
94   * @author Grigor Iliev   * @author Grigor Iliev
95   */   */
96  public class MainFrame extends JSMainFrame {  public class MainFrame extends JSMainFrame {
         private final FantasiaMenuBar menuBar = new FantasiaMenuBar();  
97          private final StandardBar standardBar = new StandardBar();          private final StandardBar standardBar = new StandardBar();
98            private final FantasiaMenuBar menuBar = new FantasiaMenuBar();
99            private final JPanel rootPane = new JPanel();
100          private final MainPane mainPane = new MainPane();          private final MainPane mainPane = new MainPane();
         private final DevicesPane devicesPane = new DevicesPane();  
101                    
102          private final JMenu recentScriptsMenu =          private final JMenu recentScriptsMenu =
103                  new JMenu(i18n.getMenuLabel("actions.recentScripts"));                  new JMenu(i18n.getMenuLabel("actions.recentScripts"));
104                    
105          private final JSplitPane hSplitPane;          private final JSplitPane hSplitPane;
106                    
107          private final SidePane sidePane = new SidePane();          private final LeftSidePane leftSidePane = new LeftSidePane();
108            private final RightSidePane rightSidePane = new RightSidePane();
109            private final JPanel rightPane;
110                    
111          private LSConsoleFrame lsConsoleFrame = null;          private final LSConsoleFrame lsConsoleFrame = new LSConsoleFrame();
112          private final Vector<String> recentScripts = new Vector<String>();          private final Vector<String> recentScripts = new Vector<String>();
113                                    
114                    
115            private final JCheckBoxMenuItem cbmiToolBarVisible =
116                            new JCheckBoxMenuItem(i18n.getMenuLabel("view.toolBar"));
117            
118            private final JCheckBoxMenuItem cbmiLeftSidePaneVisible =
119                            new JCheckBoxMenuItem(i18n.getMenuLabel("view.leftSidePane"));
120            
121            private final JCheckBoxMenuItem cbmiRightSidePaneVisible =
122                            new JCheckBoxMenuItem(i18n.getMenuLabel("view.rightSidePane"));
123            
124          /** Creates a new instance of <code>MainFrame</code> */          /** Creates a new instance of <code>MainFrame</code> */
125          public          public
126          MainFrame() {          MainFrame() {
# Line 114  public class MainFrame extends JSMainFra Line 130  public class MainFrame extends JSMainFra
130                                    
131                  getContentPane().add(standardBar, BorderLayout.NORTH);                  getContentPane().add(standardBar, BorderLayout.NORTH);
132                                    
133                  addMenu();                  rightPane = createRightPane();
                   
                 addChannelsPane(mainPane.getChannelsPane());  
                   
                 JScrollPane sp = new JScrollPane(createRightPane());  
                 sp.setBorder(BorderFactory.createEmptyBorder());  
134                                    
135                  hSplitPane = new JSplitPane (                  hSplitPane = new JSplitPane (
136                          JSplitPane.HORIZONTAL_SPLIT,                          JSplitPane.HORIZONTAL_SPLIT,
137                          true,   // continuousLayout                          true,   // continuousLayout
138                          sidePane, sp                          leftSidePane, rightPane
139                  );                  );
140                    hSplitPane.setResizeWeight(0.5);
141                    
142                    rootPane.setLayout(new BorderLayout());
143                    rootPane.setBorder(BorderFactory.createEmptyBorder(6, 0, 0, 0));
144                    rootPane.setOpaque(false);
145                    rootPane.add(hSplitPane);
146                    
147                    addMenu();
148                    
149                    addChannelsPane(mainPane.getChannelsPane());
150                                    
151                  getContentPane().add(hSplitPane);                  getContentPane().add(rootPane);
152                                    
153                  int i = preferences().getIntProperty("MainFrame.hSplitDividerLocation", 220);                  int i = preferences().getIntProperty("MainFrame.hSplitDividerLocation", 220);
154                  hSplitPane.setDividerLocation(i);                  hSplitPane.setDividerLocation(i);
# Line 149  public class MainFrame extends JSMainFra Line 170  public class MainFrame extends JSMainFra
170                  c.gridy = 0;                  c.gridy = 0;
171                  c.weightx = 1.0;                  c.weightx = 1.0;
172                  c.weighty = 1.0;                  c.weighty = 1.0;
173                  c.insets = new Insets(0, 3, 3, 0);                  c.insets = new Insets(0, 3, 0, 0);
174                  gridbag.setConstraints(devicesPane, c);                  gridbag.setConstraints(rightSidePane, c);
175                  p.add(devicesPane);                  p.add(rightSidePane);
176                                    
177                  c.gridx = 0;                  c.gridx = 0;
178                  c.gridy = 0;                  c.gridy = 0;
179                  c.weightx = 0.0;                  c.weightx = 0.0;
180                  c.weighty = 1.0;                  c.weighty = 1.0;
181                  c.insets = new Insets(0, 3, 3, 3);                  c.insets = new Insets(0, 3, 0, 3);
182                  c.fill = GridBagConstraints.VERTICAL;                  c.fill = GridBagConstraints.VERTICAL;
183                  gridbag.setConstraints(mainPane, c);                  gridbag.setConstraints(mainPane, c);
184                  p.add(mainPane);                  p.add(mainPane);
# Line 211  public class MainFrame extends JSMainFra Line 232  public class MainFrame extends JSMainFra
232          /** Invoked when this window is about to close. */          /** Invoked when this window is about to close. */
233          protected void          protected void
234          onWindowClose() {          onWindowClose() {
235                  sidePane.savePreferences();                  boolean b = preferences().getBoolProperty(CONFIRM_APP_QUIT);
236                    if(b && CC.getSamplerModel().isModified()) {
237                            JSQuitDlg dlg = new JSQuitDlg(Res.iconQuestion32);
238                            dlg.setVisible(true);
239                            if(dlg.isCancelled()) return;
240                    }
241                    
242                    leftSidePane.savePreferences();
243                    rightSidePane.savePreferences();
244                                    
245                  int i = hSplitPane.getDividerLocation();                  int i = hSplitPane.getDividerLocation();
246                  preferences().setIntProperty("MainFrame.hSplitDividerLocation", i);                  preferences().setIntProperty("MainFrame.hSplitDividerLocation", i);
# Line 253  public class MainFrame extends JSMainFra Line 282  public class MainFrame extends JSMainFra
282                  // Actions                  // Actions
283                  m = new FantasiaMenu(i18n.getMenuLabel("actions"));                  m = new FantasiaMenu(i18n.getMenuLabel("actions"));
284                                    
285                  mi = new JMenuItem(a4n.connect);                  mi = new JMenuItem(a4n.refresh);
286                  mi.setIcon(null);                  mi.setIcon(null);
287                  //mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_N, KeyEvent.CTRL_MASK));                  mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_F5, 0));
288                  m.add(mi);                  m.add(mi);
289                                    
290                  mi = new JMenuItem(a4n.samplerInfo);                  mi = new JMenuItem(a4n.samplerInfo);
291                  mi.setIcon(null);                  mi.setIcon(null);
292                  m.add(mi);                  m.add(mi);
293                                    
294                    mi = new JMenuItem(a4n.resetSampler);
295                    mi.setIcon(null);
296                    m.add(mi);
297                    
298                  m.addSeparator();                  m.addSeparator();
299                                    
300                  JMenu exportMenu = new JMenu(i18n.getMenuLabel("actions.export"));                  JMenu exportMenu = new JMenu(i18n.getMenuLabel("actions.export"));
# Line 280  public class MainFrame extends JSMainFra Line 313  public class MainFrame extends JSMainFra
313                                    
314                  mi = new JMenuItem(a4n.loadScript);                  mi = new JMenuItem(a4n.loadScript);
315                  mi.setIcon(null);                  mi.setIcon(null);
316                    mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_O, KeyEvent.CTRL_MASK));
317                  m.add(mi);                  m.add(mi);
318                                    
319                  String[] list = preferences().getStringListProperty(RECENT_LSCP_SCRIPTS);                  String[] list = preferences().getStringListProperty(RECENT_LSCP_SCRIPTS);
# Line 291  public class MainFrame extends JSMainFra Line 325  public class MainFrame extends JSMainFra
325                                    
326                  m.addSeparator();                  m.addSeparator();
327                                    
328                    mi = new JMenuItem(a4n.changeBackend);
329                    mi.setIcon(null);
330                    mi.setAccelerator(KeyStroke.getKeyStroke(KeyEvent.VK_B, KeyEvent.CTRL_MASK));
331                    m.add(mi);
332                    
333                    m.addSeparator();
334                    
335                  mi = new JMenuItem(i18n.getMenuLabel("actions.exit"));                  mi = new JMenuItem(i18n.getMenuLabel("actions.exit"));
336                  m.add(mi);                  m.add(mi);
337                  mi.addActionListener(new ActionListener() {                  mi.addActionListener(new ActionListener() {
# Line 305  public class MainFrame extends JSMainFra Line 346  public class MainFrame extends JSMainFra
346                  m = new FantasiaMenu(i18n.getMenuLabel("edit"));                  m = new FantasiaMenu(i18n.getMenuLabel("edit"));
347                  menuBar.add(m);                  menuBar.add(m);
348                                    
349                    mi = new JMenuItem(i18n.getMenuLabel("edit.addChannel"));
350                    m.add(mi);
351                    mi.addActionListener(new ActionListener() {
352                            public void
353                            actionPerformed(ActionEvent e) {
354                                    CC.getSamplerModel().addBackendChannel();
355                            }
356                    });
357                    
358                    m.addSeparator();
359                    
360                    mi = new JMenuItem(a4n.createMidiDevice);
361                    mi.setIcon(null);
362                    m.add(mi);
363                    
364                    mi = new JMenuItem(a4n.createAudioDevice);
365                    mi.setIcon(null);
366                    m.add(mi);
367                    
368                    m.addSeparator();
369                    
370                  mi = new JMenuItem(a4n.editPreferences);                  mi = new JMenuItem(a4n.editPreferences);
371                  mi.setIcon(null);                  mi.setIcon(null);
372                  mi.setAccelerator(KeyStroke.getKeyStroke (                  mi.setAccelerator(KeyStroke.getKeyStroke (
# Line 312  public class MainFrame extends JSMainFra Line 374  public class MainFrame extends JSMainFra
374                  ));                  ));
375                  m.add(mi);                  m.add(mi);
376                                    
377                    // View
378                    m = new FantasiaMenu(i18n.getMenuLabel("view"));
379                    menuBar.add(m);
380                    
381                    m.add(cbmiToolBarVisible);
382                    
383                    cbmiToolBarVisible.addActionListener(new ActionListener() {
384                            public void
385                            actionPerformed(ActionEvent e) {
386                                    showToolBar(cbmiToolBarVisible.getState());
387                            }
388                    });
389                    
390                    boolean b = preferences().getBoolProperty("toolBar.visible");
391                    cbmiToolBarVisible.setSelected(b);
392                    showToolBar(b);
393                    
394                    cbmiLeftSidePaneVisible.setAccelerator(KeyStroke.getKeyStroke (
395                            KeyEvent.VK_L, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK
396                    ));
397                    m.add(cbmiLeftSidePaneVisible);
398                    
399                    cbmiLeftSidePaneVisible.addActionListener(new ActionListener() {
400                            public void
401                            actionPerformed(ActionEvent e) {
402                                    showSidePane(cbmiLeftSidePaneVisible.getState());
403                            }
404                    });
405                    
406                    b = preferences().getBoolProperty("leftSidePane.visible");
407                    cbmiLeftSidePaneVisible.setSelected(b);
408                    showSidePane(b);
409                    
410                    cbmiRightSidePaneVisible.setAccelerator(KeyStroke.getKeyStroke (
411                            KeyEvent.VK_R, KeyEvent.CTRL_MASK | KeyEvent.SHIFT_MASK
412                    ));
413                    m.add(cbmiRightSidePaneVisible);
414                    
415                    cbmiRightSidePaneVisible.addActionListener(new ActionListener() {
416                            public void
417                            actionPerformed(ActionEvent e) {
418                                    showDevicesPane(cbmiRightSidePaneVisible.getState());
419                            }
420                    });
421                    
422                    b = preferences().getBoolProperty("rightSidePane.visible");
423                    cbmiRightSidePaneVisible.setSelected(b);
424                    showDevicesPane(b);
425                    
426                                    
427                  // Window                  // Window
428                  m = new FantasiaMenu(i18n.getMenuLabel("window"));                  m = new FantasiaMenu(i18n.getMenuLabel("window"));
# Line 329  public class MainFrame extends JSMainFra Line 440  public class MainFrame extends JSMainFra
440                  // Help                  // Help
441                  m = new FantasiaMenu(i18n.getMenuLabel("help"));                  m = new FantasiaMenu(i18n.getMenuLabel("help"));
442                                    
443                    mi = new JMenuItem(a4n.browseOnlineTutorial);
444                    mi.setIcon(null);
445                    m.add(mi);
446                    
447                    m.addSeparator();
448                    
449                  mi = new JMenuItem(a4n.helpAbout);                  mi = new JMenuItem(a4n.helpAbout);
450                  mi.setIcon(null);                  mi.setIcon(null);
451                  m.add(mi);                  m.add(mi);
# Line 371  public class MainFrame extends JSMainFra Line 488  public class MainFrame extends JSMainFra
488                    
489          public void          public void
490          showDetailedErrorMessage(Frame owner, String err, String details) {          showDetailedErrorMessage(Frame owner, String err, String details) {
491                  // TODO:                  JSDetailedErrorDlg dlg = new JSDetailedErrorDlg (
492                            owner, Res.iconWarning32, i18n.getError("error"), err, details
493                    );
494                    dlg.setVisible(true);
495          }          }
496                    
497          public void          public void
498          showDetailedErrorMessage(Dialog owner, String err, String details) {          showDetailedErrorMessage(Dialog owner, String err, String details) {
499                  // TODO:                  JSDetailedErrorDlg dlg = new JSDetailedErrorDlg (
500                            owner, Res.iconWarning32, i18n.getError("error"), err, details
501                    );
502                    dlg.setVisible(true);
503            }
504            
505            /**
506             * Gets the server address to which to connect. If the server should be
507             * manually selected, a dialog asking the user to choose a server is displayed.
508             */
509            public Server
510            getServer() {
511                    boolean b = preferences().getBoolProperty(MANUAL_SERVER_SELECT_ON_STARTUP);
512                    return getServer(b);
513            }
514            
515            /**
516             * Gets the server address to which to connect. If the server should be
517             * manually selected, a dialog asking the user to choose a server is displayed.
518             * @param manualSelect Determines whether the server should be manually selected.
519             */
520            public Server
521            getServer(boolean manualSelect) {
522                    if(manualSelect) {
523                            JSConnectDlg dlg = new JSConnectDlg();
524                            dlg.setVisible(true);
525                            return dlg.getSelectedServer();
526                    }
527                    
528                    int i = preferences().getIntProperty(SERVER_INDEX);
529                    int size = CC.getServerList().getServerCount();
530                    if(size == 0) return null;
531                    if(i >= size) return CC.getServerList().getServer(0);
532                    
533                    return CC.getServerList().getServer(i);
534          }          }
535                    
536          protected LSConsoleModel          protected LSConsoleModel
# Line 388  public class MainFrame extends JSMainFra Line 542  public class MainFrame extends JSMainFra
542          }          }
543                    
544          protected LSConsoleFrame          protected LSConsoleFrame
545          getLSConsoleFrame() {          getLSConsoleFrame() { return lsConsoleFrame; }
                 if(lsConsoleFrame == null) lsConsoleFrame = new LSConsoleFrame();  
                 return lsConsoleFrame;  
         }  
546                    
547          protected void          protected boolean
548          runScript() {          runScript() {
549                  String s = preferences().getStringProperty("lastScriptLocation");                  String s = preferences().getStringProperty("lastScriptLocation");
550                  JFileChooser fc = new JFileChooser(s);                  JFileChooser fc = new JFileChooser(s);
551                  fc.setFileFilter(new LscpFileFilter());                  fc.setFileFilter(new LscpFileFilter());
552                  int result = fc.showOpenDialog(this);                  int result = fc.showOpenDialog(this);
553                  if(result != JFileChooser.APPROVE_OPTION) return;                  if(result != JFileChooser.APPROVE_OPTION) return false;
554                                    
555                  String path = fc.getCurrentDirectory().getAbsolutePath();                  String path = fc.getCurrentDirectory().getAbsolutePath();
556                  preferences().setStringProperty("lastScriptLocation", path);                  preferences().setStringProperty("lastScriptLocation", path);
557                                                                                    
558                  runScript(fc.getSelectedFile());                  runScript(fc.getSelectedFile());
559                    
560                    return true;
561          }          }
562                    
563          private void          private void
# Line 464  public class MainFrame extends JSMainFra Line 617  public class MainFrame extends JSMainFra
617                  recentScriptsMenu.setEnabled(recentScripts.size() != 0);                  recentScriptsMenu.setEnabled(recentScripts.size() != 0);
618          }          }
619                    
620            private void
621            showToolBar(boolean b) {
622                    preferences().setBoolProperty("toolBar.visible", b);
623                    standardBar.setVisible(b);
624            }
625            
626            private void
627            showSidePane(boolean b) {
628                    preferences().setBoolProperty("leftSidePane.visible", b);
629                    rootPane.remove(rightPane);
630                    rootPane.remove(hSplitPane);
631                    
632                    if(b) {
633                            hSplitPane.setRightComponent(rightPane);
634                            rootPane.add(hSplitPane);
635                            int i = preferences().getIntProperty("MainFrame.hSplitDividerLocation", 220);
636                            
637                            hSplitPane.setDividerLocation(i);
638                            hSplitPane.validate();
639                    } else {
640                            rootPane.add(rightPane);
641                            
642                    }
643                    
644                    int w = getPreferredSize().width;
645                    int h = getSize().height;
646                    setSize(new Dimension(w, h));
647                    
648                    rootPane.revalidate();
649                    rootPane.validate();
650                    rootPane.repaint();
651                    
652                    SwingUtilities.invokeLater(new Runnable() {
653                            public void
654                            run() { sidePanesVisibilityChanged(); }
655                    });
656            }
657            
658            private void
659            showDevicesPane(boolean b) {
660                    preferences().setBoolProperty("rightSidePane.visible", b);
661                    
662                    int width = leftSidePane.getWidth();
663                    int height = leftSidePane.getPreferredSize().height;
664                    if(width != 0) leftSidePane.setPreferredSize(new Dimension(width, height));
665                    
666                    if(b) {
667                            int w = preferences().getIntProperty("devicesPane.width", 200);
668                            
669                            int h = rightSidePane.getPreferredSize().height;
670                            rightSidePane.setPreferredSize(new Dimension(w, h));
671                    } else {
672                            int w = rightSidePane.getWidth();
673                            if(w > 0 && w < 200) w = 200;
674                            if(w != 0) preferences().setIntProperty("devicesPane.width", w);
675                    }
676                    
677                    hSplitPane.setResizeWeight(0.0);
678                    rightSidePane.setVisible(b);
679                    hSplitPane.resetToPreferredSizes();
680                    
681                    int w = getPreferredSize().width;
682                    int h = getSize().height;
683                    setSize(new Dimension(w, h));
684                    
685                    rootPane.validate();
686                    rootPane.repaint();
687                    //hSplitPane.validate();
688                    
689                    SwingUtilities.invokeLater(new Runnable() {
690                            public void
691                            run() { sidePanesVisibilityChanged(); }
692                    });
693            }
694            
695            private void
696            sidePanesVisibilityChanged() {
697                    boolean leftSidePaneVisible = cbmiLeftSidePaneVisible.isSelected();
698                    boolean rightSidePaneVisible = cbmiRightSidePaneVisible.isSelected();
699                    
700                    if(leftSidePaneVisible && rightSidePaneVisible) {
701                            hSplitPane.setResizeWeight(0.5);
702                    } else if(leftSidePaneVisible && !rightSidePaneVisible) {
703                            hSplitPane.setResizeWeight(1.0);
704                    }
705                    
706                    if(!leftSidePaneVisible && !rightSidePaneVisible) {
707                            standardBar.showFantasiaLogo(false);
708                            if(isResizable()) setResizable(false);
709                    } else {
710                            standardBar.showFantasiaLogo(true);
711                            if(!isResizable()) setResizable(true);
712                    }
713            }
714            
715          private class RecentScriptHandler implements ActionListener {          private class RecentScriptHandler implements ActionListener {
716                  private String script;                  private String script;
717                                    
# Line 486  public class MainFrame extends JSMainFra Line 734  public class MainFrame extends JSMainFra
734                  }                  }
735          }          }
736    
737          private static class FantasiaMenuBar extends JMenuBar {          private class FantasiaMenuBar extends JMenuBar {
738                  private static Insets pixmapInsets = new Insets(6, 6, 0, 6);                  private Insets pixmapInsets = new Insets(6, 6, 0, 6);
739                    private Insets pixmapInsets2 = new Insets(6, 6, 6, 6);
740                                    
741                  FantasiaMenuBar() {                  FantasiaMenuBar() {
742                          setOpaque(false);                          setOpaque(false);
# Line 496  public class MainFrame extends JSMainFra Line 745  public class MainFrame extends JSMainFra
745                  protected void                  protected void
746                  paintComponent(Graphics g) {                  paintComponent(Graphics g) {
747                          super.paintComponent(g);                          super.paintComponent(g);
748                                                    if(standardBar.isVisible()) {
749                          PixmapPane.paintComponent(this, g, Res.gfxMenuBarBg, pixmapInsets);                                  PixmapPane.paintComponent(this, g, Res.gfxMenuBarBg, pixmapInsets);
750                            } else {
751                                    PixmapPane.paintComponent(this, g, Res.gfxRoundBg14, pixmapInsets2);
752                            }
753                  }                  }
754          }          }
755  }  }

Legend:
Removed from v.1308  
changed lines
  Added in v.1729

  ViewVC Help
Powered by ViewVC