Changeset 4346


Ignore:
Timestamp:
2003-05-27T14:53:30+12:00 (21 years ago)
Author:
kjdon
Message:

added in a log history list for build messages

Location:
trunk/gli/src/org/greenstone/gatherer/gui
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/gli/src/org/greenstone/gatherer/gui/CreatePane.java

    r4306 r4346  
    112112     /** The pane which contains the progress information. */
    113113     private JPanel progress_pane = null;
     114    /** the pane on the right-hand side - shows the requested options view */
     115    private JPanel right = null;
    114116     /** This pane is the one that is updated to show the requested options view. */
    115      private JPanel target_pane = null;
    116      /** The scrolling pane the log is inside. */
    117      private JScrollPane scroll_log = null;
    118      private JScrollPane scroll_pane;
     117    //private JPanel target_pane = null;
     118    /** The scrolling pane the log is inside. */
     119    private JScrollPane scroll_log = null;
     120    /** the scrolling pane the righthand side is inside - only used for import and build options. the log and log list are not inside a scrollpane */
     121    private JScrollPane scroll_pane;
    119122     /** The log for the current process. */
    120123     private JTextArea process_log = null;
     
    146149      */
    147150     public CreatePane() {
    148           this.target_pane = new JPanel(new BorderLayout());
     151         //this.target_pane = new JPanel(new BorderLayout());
    149152          Collection collection = Gatherer.c_man.getCollection();
    150           if(collection != null) {
    151                 this.options_pane = new OptionsPane(target_pane, message_log, collection.build_options);
    152           }
     153          //if(collection != null) {
     154          //    this.options_pane = new OptionsPane(message_log, collection.build_options);
     155          // }
    153156          // Create components
    154157          card_layout = new CardLayout();
     
    209212      */
    210213     public void collectionChanged(boolean ready) {
    211           ///ystem.err.println("Collection changed... ");
     214         ///ystem.err.println("Collection changed... ");
    212215          if(Gatherer.c_man != null && Gatherer.c_man.ready()) {
    213                 this.options_pane = new OptionsPane(target_pane, message_log, Gatherer.c_man.getCollection().build_options);
     216             
     217              if (!processing &&this.options_pane!=null) {
     218              // we only do this if we are not processing - if we are processing, then we haven't added the new entry yet, and it will be added by another method
     219              this.options_pane.resetLogList(); // saves any residual message
     220              }
     221              this.options_pane = new OptionsPane(message_log, Gatherer.c_man.getCollection().build_options);
     222              tree.valueChanged(null);
    214223          }
    215224     }
     
    230239          left.add(tree, BorderLayout.CENTER);
    231240
    232           JPanel right = new JPanel();
     241          right = new JPanel();
    233242          right.setBorder(BorderFactory.createEmptyBorder(0,0,5,5));
    234243          right.setLayout(new BorderLayout());
    235           scroll_pane = new JScrollPane(target_pane);
    236           right.add(scroll_pane, BorderLayout.CENTER);
     244          //scroll_pane = new JScrollPane(target_pane);
     245          //right.add(scroll_pane, BorderLayout.CENTER);
    237246
    238247          JPanel options_area = new JPanel();
     
    358367      * @param event A <strong>GShellEvent</strong> that contains details of the final state of the <strong>GShell</strong> after task completion.
    359368      */
    360      public synchronized void processComplete(GShellEvent event) {
    361           if(event.getType() == GShell.BUILD) {
    362                 processing = false;
    363                 cancel_button.setEnabled(false);
    364                 build_button.setEnabled(true);
    365                 card_layout.show(main_pane, CONTROL);
    366           }
    367      }
     369    public synchronized void processComplete(GShellEvent event) {
     370    if(event.getType() == GShell.BUILD) {
     371        processing = false;
     372        cancel_button.setEnabled(false);
     373        build_button.setEnabled(true);
     374        int status = event.getStatus();
     375        if (status == GShell.OK) {
     376        options_pane.addNewLog(OptionsPane.SUCCESSFUL);
     377        } else {
     378        options_pane.addNewLog(OptionsPane.UNSUCCESSFUL);
     379        }
     380        card_layout.show(main_pane, CONTROL);
     381    }
     382    }
    368383     /** This method retrieves a phrase from the dictionary based apon the key.
    369384      * @param key A <strong>String</strong> used as a reference to the correct phrase.
     
    409424                scroll_log = new JScrollPane(process_log);
    410425                progress_pane.add(scroll_log, BorderLayout.CENTER);
     426                // clear the log list and message_log
     427                options_pane.resetLogList();
    411428                // Change the view.
    412429                processing = true;
     
    437454                build_button.setEnabled(true);
    438455                cancel_button.setEnabled(false);
     456                processing = false;
     457                options_pane.addNewLog(OptionsPane.CANCELLED);
    439458                card_layout.show(main_pane, CONTROL);
    440459                // Set the stop flag in all the process monitor.
     
    496515                TreePath path = null;
    497516                OptionTreeNode node = null;
    498                 if(event != null) {
    499                      path = event.getPath();
    500                      node = (OptionTreeNode)path.getLastPathComponent();
    501                 }
     517                //if(event != null) {
     518                    //path = event.getPath();
     519                    path = getSelectionPath();
     520                    if(path != null) {
     521                    node = (OptionTreeNode)path.getLastPathComponent();
     522                    }
     523                //}
    502524                if(previous_pane != null) {
    503525                     //target_pane.remove(previous_pane);
    504526                     options_pane.update(previous_pane);
     527                     if(scroll_pane != null) {
     528                         right.remove(scroll_pane);
     529                     }
     530                     else {
     531                         right.remove(previous_pane);
     532                     }
    505533                     previous_pane = null;
     534                     scroll_pane = null;
    506535                }
    507536                if(node != null && node.equals(building)) {
    508537                     previous_pane = options_pane.buildBuild();
     538                     scroll_pane = new JScrollPane(previous_pane);
     539                     right.add(scroll_pane, BorderLayout.CENTER);
    509540                     //target_pane.add(previous_pane, BorderLayout.CENTER);
    510541                }
    511542                else if(node != null && node.equals(importing)) {
    512543                     previous_pane = options_pane.buildImport();
     544                     scroll_pane = new JScrollPane(previous_pane);
     545                     right.add(scroll_pane, BorderLayout.CENTER);
    513546                     //target_pane.add(previous_pane, BorderLayout.CENTER);
    514547                }
    515548                else {
    516549                     previous_pane = options_pane.buildLog();
     550                     right.add(previous_pane, BorderLayout.CENTER);
     551                     right.updateUI(); // we need to repaint the log pane, cos it hasn't changed since last time
     552                     ///ystem.err.println("I've added the log back to the right pane again.");
    517553                     //target_pane.add(previous_pane, BorderLayout.CENTER);
    518554                }
    519                 scroll_pane.setViewportView(previous_pane);
     555                //scroll_pane.setViewportView(previous_pane);
    520556                previous_pane.validate();
    521557          }
  • trunk/gli/src/org/greenstone/gatherer/gui/OptionsPane.java

    r4293 r4346  
    5656 */
    5757final public class OptionsPane
    58      extends JPanel {
    59      /** The <strong>BuildOptions</strong> data object contains all the option settings we wish to persist between Gatherer sessions (and thus is stored in <strong>Collection</strong>). */
    60      private BuildOptions build_options = null;
    61      /** This <strong>JPanel</strong> is used to display the varying options panes. */
    62      private JPanel target_pane = null;
    63      /** All process messages are written to this log text area. */
    64      private JTextArea log = null;
    65      static private int BUILD = 0;
    66      static private int IMPORT = 1;
    67      static private Dimension LABEL_SIZE = new Dimension(180, 25);
    68      static private Dimension LOG_SIZE = new Dimension(610, 360);
    69      /** The minimum size of a options pane, to prevent refresh problems around the bottom of shorter panes. */
    70      static private Dimension PANE_SIZE = new Dimension(610, 350);
    71      static private Dimension ROW_SIZE = new Dimension(610, 25);
    72      static private Dimension SPINNER_SIZE = new Dimension(100, 25);
    73      static private String DESCRIPTION_SEP = " + ";
     58    extends JPanel {
     59    /** The <strong>BuildOptions</strong> data object contains all the option settings we wish to persist between Gatherer sessions (and thus is stored in <strong>Collection</strong>). */
     60    private BuildOptions build_options = null;
     61    /** the log pane - we only create it once now, not each time */
     62    private JPanel log_pane = null;
     63    /** the list of previous log messages */
     64    private JList log_list = null;
     65    /** whether that currently showing log is changed or not */
     66    private boolean is_log_changed = false;
     67    /** the list entry that is currently displayed */
     68    private FileEntry displayed_log = null;
     69    /** a listener for changes in the log text */
     70    private LogChangeListener log_change_listener = null;
     71    /** All process messages are written to this log text area. */
     72    private JTextArea log_display = null;
     73
     74    static final public char SUCCESSFUL = 's';
     75    static final public char UNSUCCESSFUL = 'u';
     76    static final public char CANCELLED = 'c';
     77   
     78    static private int BUILD = 0;
     79    static private int IMPORT = 1;
     80    static private Dimension LABEL_SIZE = new Dimension(180, 25);
     81    static private Dimension LOG_SIZE = new Dimension(610, 360);
     82    /** The minimum size of a options pane, to prevent refresh problems around the bottom of shorter panes. */
     83    static private Dimension PANE_SIZE = new Dimension(610, 350);
     84    static private Dimension ROW_SIZE = new Dimension(610, 25);
     85    static private Dimension SPINNER_SIZE = new Dimension(100, 25);
     86    static private String DESCRIPTION_SEP = " + ";
     87   
     88   
    7489     /** The default constructor creates the few session length options, but either retrieves the rest from the current collection, or creates a default set of options. */
    75      public OptionsPane(JPanel target_pane, JTextArea log, BuildOptions build_options) {
    76           this.log = log;
     90     public OptionsPane(JTextArea log, BuildOptions build_options) {
     91          this.log_display = log;
    7792          this.build_options = build_options;
    78           this.target_pane = target_pane;
    79      }
     93          this.log_change_listener = new LogChangeListener();
     94          //this.target_pane = target_pane;
     95     }
     96
     97    /** creates a new log from the text in log. The new file is named
     98     * build_log.<current time>.txt. A new FileEntry is added to teh log list
     99     * and made selected. A fresh listener is added to teh document */
     100    public void addNewLog(char success) {
     101    ///ystem.out.println("add new log");
     102       
     103    // create the file name
     104    long time = System.currentTimeMillis();
     105    StringBuffer name = new StringBuffer();
     106    name.append("build_log.");
     107    name.append(time);
     108    name.append(success);
     109    name.append(".txt");
     110    File f = new File(Gatherer.c_man.getCollectionLog()+name.toString());
     111    // just in case there is no log directory
     112    File parent_file = f.getParentFile();
     113    parent_file.mkdirs();
     114
     115    // save the log text to the file
     116    saveLogFile(f);
     117    is_log_changed=false;
     118    log_display.getDocument().addDocumentListener(log_change_listener);
     119
     120    // create the file entry and add it to the list at pos 0 - it will always be the newest one created
     121    FileEntry fe = new FileEntry(f);
     122    ((DefaultListModel)log_list.getModel()).add(0, fe);
     123    log_list.setSelectedIndex(0);
     124    displayed_log = fe;
     125
     126    }
     127
    80128     /** This method creates the panel with all the build only options on it.
    81129      * @return A <strong>JPanel</strong> which can be used to display all the build only options.
     
    134182          return pane;
    135183     }
    136      /** This method is used to build a panel based on the message log, which is nothing like any of the other panel.
     184     /** This method is used to build a panel based on the message log, which is nothing like any of the other panels.
    137185      * @return A <strong>JPanel</strong> containing a scrollable text area which represents the shell process message log.
    138186      */
    139187     public JPanel buildLog() {
    140           JPanel pane = new JPanel(new BorderLayout());
    141           /*
    142           // Build a list of the log files available, ordering by last modified. Log files end .log (duh!)
    143           DefaultComboBoxModel model = new DefaultComboBoxModel();
    144           File etc_directory = new File(gatherer.c_man.getCollectionEtc());
    145           File children[] = etc_directory.listFiles();
     188         // we now save the log pane
     189         if (log_pane == null) {
     190         log_pane = new JPanel(new BorderLayout());
     191         
     192          // Build a list of the log files available, ordering by last modified. Log files are like build_log.date.txt
     193          DefaultListModel contents = new DefaultListModel();
     194          File log_directory = new File(Gatherer.c_man.getCollectionLog());
     195          File children[] = log_directory.listFiles();
    146196          for(int i = 0; children != null && i < children.length; i++) {
    147                 if(children[i].getName().endsWith(".log")) {
    148                      FileEntry entry = new FileEntry(children[i]);
    149                      // We are about to insert it. But where.
    150                      boolean found = false;
    151                      for(int j = 0; j < model.getSize(); j++) {
    152                           FileEntry sibling = (FileEntry) model.getElementAt(i);
    153                           int order = entry.compareTo(sibling);
    154                           if(order < 0) {
    155                                 model.insertElementAt(entry, j);
    156                                 found = true;
    157                           }
    158                      }
    159                      if(!found) {
    160                           model.addElement(entry);
    161                      }
    162                 }
    163           }
    164           JComboBox logs_box = new JComboBox(model);
    165           // If log is empty, reload the most recent log.
    166           if(log.getText().length() == 0 && model.getSize() > 0) {
    167                 loadLog(model.getElementAt(0));
    168           }
    169           */
    170           pane.add(log, BorderLayout.CENTER);
    171           //pane.add(logs_box, BorderLayout.SOUTH);
    172           return pane;
     197              if(children[i].getName().startsWith("build_log")&&children[i].getName().endsWith(".txt") ) {
     198              FileEntry entry = new FileEntry(children[i]);
     199              // We are about to insert it. But where.
     200              boolean found = false;
     201              for(int j = 0; j < contents.size(); j++) {
     202                  FileEntry sibling = (FileEntry) contents.getElementAt(j);
     203                  int order = entry.compareTo(sibling);
     204                  if(order > 0) {
     205                  contents.insertElementAt(entry, j);
     206                  found = true;
     207                  break;
     208                  }
     209              }
     210              if(!found) {
     211                  contents.addElement(entry);
     212              }
     213              }
     214          }
     215         
     216          log_list = new JList(contents);
     217          log_list.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
     218          log_list.setLayoutOrientation(JList.VERTICAL);
     219          log_list.setVisibleRowCount(3);
     220          log_list.addListSelectionListener(new LogListListener());
     221         
     222          JScrollPane list_scroller = new JScrollPane(log_list);
     223         
     224          // If log is not empty and we have something in displayed_log - make that element selected
     225          if (log_display.getText().length()>0 && displayed_log != null) {
     226              int index = contents.indexOf(displayed_log);
     227              if (index != -1) {
     228              log_list.setSelectedIndex(index);
     229              }
     230             
     231          }
     232          log_pane.add(new JScrollPane(log_display), BorderLayout.CENTER);
     233          JLabel log_history_label = new JLabel(get("LogHistory"));
     234          JPanel log_history_pane = new JPanel();
     235          log_history_pane.setLayout(new BorderLayout());
     236          log_history_pane.add(log_history_label, BorderLayout.NORTH);
     237          log_history_pane.add(list_scroller, BorderLayout.SOUTH);
     238          log_pane.add(log_history_pane, BorderLayout.SOUTH);
     239         }
     240         return log_pane;
     241     }
     242
     243     /** This method retrieves a phrase from the dictionary based apon the key.
     244      * @param key A <strong>String</strong> used as a reference to the correct phrase.
     245      * @return A phrase, matching the key, as a <strong>String</strong>.
     246      */
     247     private String get(String key) {
     248          return get(key, null);
     249     }
     250     /** This method retrieves a phrase from the dictionary based apon the key and arguments.
     251      * @param key A <strong>String</strong> used as a reference to the correct phrase.
     252      * @param args A <strong>String[]</strong> whose contents are often substituted into the phrase before it is returned.
     253      * @return A phrase, matching the key and constructed using the arguments, as a <strong>String</strong>.
     254      * @see org.greenstone.gatherer.Dictionary
     255      * @see org.greenstone.gatherer.Gatherer
     256      */
     257     private String get(String key, String args[]) {
     258          if(key.indexOf(".") == -1) {
     259                key = "OptionsPane." + key;
     260          }
     261          return Gatherer.dictionary.get(key, args);
    173262     }
    174263     /** Attempts to discover the latest document count.
     
    184273          return 1;
    185274     }
    186    
    187      public void saveLog() {
    188           /*
    189           try {
    190                 long name_long = System.currentTimeMillis();
    191                 String name = name_long + ".log";
    192                 File;
    193                 FileOutputStream fos = new FileOutputStream(file);
    194           }
    195           catch(Exception error) {
    196           }
    197           */
    198      }
     275   
     276    /** Loads a new log into the log text - saves the currently showing one,
     277     * and loads the new one, adding a fresh listener to the document
     278     * Note, we need to remove any listener before making the changes, then
     279     * add a listener back in
     280     */
     281    public void loadSelectedLog(FileEntry fe) {
     282    ///ystem.out.println("load selected log");
     283    if (is_log_changed) {
     284        saveLogFile(displayed_log.getFile());
     285    } else {
     286        log_display.getDocument().removeDocumentListener(log_change_listener);
     287    }
     288   
     289    displayed_log = fe;
     290    if (fe != null) {
     291        log_display.setText(fe.getFileText());
     292    } else {
     293        log_display.setText("");
     294    }
     295    is_log_changed=false;
     296    log_display.getDocument().addDocumentListener(log_change_listener);
     297   
     298    }
     299
     300    /** Neutralizes the log list - saves any unsaved changes to the current log
     301     * clears the log text, unselects the log list, and adds a fresh listener
     302     * to the log's document
     303     * Note, we need to remove any listener before making the changes, then
     304     * add a listener back in */
     305    public void resetLogList() {
     306    ///ystem.out.println("reset log");
     307    if (is_log_changed) {
     308        saveLogFile(displayed_log.getFile());
     309    } else {
     310        log_display.getDocument().removeDocumentListener(log_change_listener);
     311    }
     312    log_display.setText("");
     313    displayed_log = null;
     314    if (log_list != null) {
     315        log_list.clearSelection();
     316    }
     317    is_log_changed=false;
     318    log_display.getDocument().addDocumentListener(log_change_listener);
     319   
     320    }
     321
     322    /** saves the current text in log to the File specified */
     323    public void saveLogFile(File file) {
     324   
     325    try {
     326        BufferedWriter out = new BufferedWriter(new FileWriter(file)); // uses the default encoding
     327        String log_text = log_display.getText();
     328        // set teh return delims to true, then swap them for newLine() (platform dependent) - having return delims set to false seemed to not get empty strings so that empty lines were not preserved.
     329        StringTokenizer t = new StringTokenizer(log_text, "\n", true);
     330        while (t.hasMoreTokens()) {
     331        String token = t.nextToken();
     332        if (token.equals("\n")) {
     333            out.newLine();
     334        } else {
     335            out.write(token, 0, token.length());
     336        }
     337       
     338        }
     339        out.close();
     340       
     341    } catch(Exception e) {
     342        System.out.println("Error in saving log file: "+file.toString());
     343        e.printStackTrace();
     344    }
     345   
     346   
     347    }
     348
    199349
    200350     /** Given a panel containing ArgumentControls, update the values associated with them. */
    201351     public void update(JPanel panel) {
     352         if(panel == log_pane) {
     353         return;
     354         }
     355
    202356          for(int i = 0; i < panel.getComponentCount(); i++) {
    203357                Component component = panel.getComponent(i);
     
    432586     }
    433587
     588    /** holds a File which has a particular naming convention
     589     * build_log.date.txt
     590     * also keeps a Date corresponding to the date in its name*/
     591    private class FileEntry {
     592   
     593    private Date date=null;
     594    private File file=null;
     595    private String display=null;
     596    public FileEntry(File f) {
     597        this.file=f;
     598        this.date = getDateFromFileName();
     599        this.display = createDisplayText();
     600       
     601    }
     602
     603    /** returns 0 if the dates are the same, -ve number if the current FileEntry is earlier than the fe FileEntry ...*/
     604    public int compareTo(FileEntry fe) {
     605        Date d = fe.getDate();
     606        return date.compareTo(d);
     607    }
     608   
     609    public Date getDate() {
     610        return this.date;
     611    }
     612    public File getFile() {
     613        return this.file;
     614    }
     615    /** returns the contents of the file */
     616    public String getFileText() {
     617        if (!this.file.exists()) {
     618        return "";
     619        }
     620        StringBuffer contents = new StringBuffer();
     621        try {
     622        BufferedReader in = new BufferedReader(new FileReader(this.file));
     623        String line;
     624       
     625        while ((line = in.readLine()) != null) {
     626            contents.append(line);
     627            contents.append("\n");
     628        }
     629        } catch (FileNotFoundException fnfe) {
     630        System.err.println("Error: log file not found: "+ this.file.toString());
     631        return "";
     632        } catch (IOException ioe) {
     633        System.err.println("Error: exception occurred when trying to read in file "+this.file.toString()+", "+ioe.getMessage());
     634       
     635        }
     636       
     637        return contents.toString();
     638    }
     639    /** we only want the date out of the file name, not the whole path */
     640    public String toString() {
     641        return this.display;
     642    }
     643    /** creates the display text for the list */
     644    private String createDisplayText() {
     645        StringBuffer d = new StringBuffer();
     646        d.append(date.toString());
     647        char success= this.file.getName().charAt(23);
     648        switch (success) {
     649        case OptionsPane.SUCCESSFUL:
     650        d.append(get("Successful"));
     651        break;
     652        case OptionsPane.UNSUCCESSFUL:
     653        d.append(get("Unsuccessful"));
     654        break;
     655        case OptionsPane.CANCELLED:
     656        d.append(get("Cancelled"));
     657        break;
     658        }
     659        return d.toString();
     660    }
     661    /** extracts the date from the file name */
     662    private Date getDateFromFileName() {
     663        String name = this.file.getName();
     664        String date_string = name.substring(10, 23);//name.length()-4);
     665        return new Date(Long.parseLong(date_string));
     666    }
     667
     668   
     669    }
     670
     671    /** A DocumentListener that listens for changes in the log_display document
     672     * if a change is registered, the flag is_log_changed is set to true,
     673     * and the listener removes itself from log_display
     674     * Because we only want to register user's changes, the listener must be removed before the system makes any changes, and then put back. For example, each time we switchlogs to display, a remove event and an insert event are sent. We dont want to register these as changes to the document, so the listener must be removed before the switch, and added back afterwards */
     675    private class LogChangeListener implements DocumentListener {
     676
     677    public void changedUpdate(DocumentEvent e) {
     678        ///ystem.out.println("changed update");
     679        registerChange();
     680    }
     681    public void insertUpdate(DocumentEvent e) {
     682        ///ystem.out.println("insert update");
     683        registerChange();
     684    }
     685    public void removeUpdate(DocumentEvent e) {
     686        ///ystem.out.println("remove update");
     687        registerChange();
     688    }
     689
     690    private void registerChange() {
     691        ///ystem.err.println("a change in the doc occurred, removing the listener");
     692        is_log_changed = true;
     693        log_display.getDocument().removeDocumentListener(this);
     694    }
     695    }
     696   
     697    /** a ListSelectionListener that triggers the load of a newly selected
     698    log */
     699    private class LogListListener implements ListSelectionListener {
     700
     701    public void valueChanged(ListSelectionEvent e) {
     702        if (!e.getValueIsAdjusting()) { // we get two events for one change in list selection - use the false one ( the second one)
     703        JList source  = (JList)e.getSource();
     704        FileEntry fe = (FileEntry) source.getSelectedValue();
     705        loadSelectedLog(fe);
     706        }
     707    }
     708    }
     709
    434710     /** Listener that sets the tooltip associated to a combobox to the tooltip relevant to the selected item. */
    435711     private class ToolTipUpdater
     
    462738          }
    463739     }
     740
     741
    464742}
Note: See TracChangeset for help on using the changeset viewer.