Clover coverage report -
Coverage timestamp: Sun Apr 18 2004 21:32:30 EDT
file stats: LOC: 868   Methods: 34
NCLOC: 508   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
FindReplaceDialog.java 33.3% 60.1% 50% 55.4%
coverage coverage
 1   
 import javax.swing.*;
 2   
 import java.awt.*;
 3   
 import javax.swing.border.*;
 4   
 import java.awt.event.*;
 5   
 import javax.swing.text.Document;
 6   
 import java.util.*;
 7   
 //import com.lightdev.app.shtm.FrmMain;
 8   
 
 9   
 /**
 10   
  * Dialog to manage find and replace on a <code>Document</code> shown
 11   
  * in a <code>JEditorPane</code>.
 12   
  *
 13   
  * <p>The component has a 'pluggable' interface about how to deal with the
 14   
  * event that one document has been searched to the end. If it is
 15   
  * constructed with a FindReplaceListener, it shows an additional
 16   
  * checkbox 'Whole project' where the user can select, if a group of
 17   
  * documents shall be searched instead of a single document.</p>
 18   
  *
 19   
  * <p>If only one document is searched, the dialog searches only in the
 20   
  * document currently shown in the editor.</p>
 21   
  *
 22   
  * <p>By adding a FindReplaceListener listening for FindReplaceEvents,
 23   
  * the FindReplaceDialog notifies other classes about the fact that a
 24   
  * group of documents shall be searched instead of only the current one.</p>
 25   
  *
 26   
  * <p>Initially FindReplaceDialog notifies the listener that the first document
 27   
  * in the group shall be loaded into the editor.</p>
 28   
  *
 29   
  * <p>After loading the first document and resuming the find or replace
 30   
  * operation, the listener gets informed that the end of a document has been
 31   
  * reached. A handling method for that event should cause the editor to
 32   
  * load the next document in the group before it resumes the find or
 33   
  * replace operation.</p>
 34   
  *
 35   
  * <p><b>Example for an implementation of FindReplaceListener:</b></p>
 36   
  * <p><b>IMPORTANT: </b>the methods of the FindReplaceListener need to
 37   
  * call either resumeOperation() or terminateOperation() on the
 38   
  * FindReplaceDialog, that fired the FindReplaceEvent. Otherwise
 39   
  * the FindReplaceDialog could 'hang'.</p>
 40   
  * <p>
 41   
  * <pre>
 42   
  *   FindReplaceDialog frd = new FindReplaceDialog(aFrame,
 43   
  *                             myEditorPane, new MyFindReplaceListener());
 44   
  *
 45   
  *   protected class MyFindReplaceListener implements FindReplaceListener {
 46   
  *     public void getNextDocument(FindReplaceEvent e) {
 47   
  *       if(documentsLeft()) { // documentsLeft() is a method coded somewhere else
 48   
  *         myEditorPane.setDocument(nextDocument()); // nextDocument() is a method coded somewhere else
 49   
  *         ((FindReplaceDialog) e.getSource()).resumeOperation();
 50   
  *       }
 51   
  *       else {
 52   
  *         ((FindReplaceDialog) e.getSource()).terminateOperation();
 53   
  *       }
 54   
  *     }
 55   
  *
 56   
  *     public void getFirstDocument(FindReplaceEvent e) {
 57   
  *       myEditorPane.setDocument(firstDocument()); // firstDocument() is a method coded somewhere else
 58   
  *       ((FindReplaceDialog) e.getSource()).resumeOperation();
 59   
  *     }
 60   
  *   }
 61   
  * </pre>
 62   
  * </p>
 63   
  *
 64   
  * <p>Added i18n support for application SimplyHTML in version 1.5</p>
 65   
  *
 66   
  * @author Ulrich Hilger
 67   
  * @author CalCom
 68   
  * @author <a href="http://www.calcom.de">http://www.calcom.de</a>
 69   
  * @author <a href="mailto:info@calcom.de">info@calcom.de</a>
 70   
  *
 71   
  * @version 1.5, April 27, 2003
 72   
  *
 73   
  * @see javax.swing.text.Document
 74   
  * @see javax.swing.JEditorPane
 75   
  */
 76   
 
 77   
 public class FindReplaceDialog extends JDialog {
 78   
 
 79   
 
 80   
   /* ---- Constructor(s) start -----------*/
 81   
 
 82   
   /**
 83   
    * Construct a <code>FindReplaceDialog</code>.
 84   
    *
 85   
    * <p>Does not show the dialog window, as fields 'editor' and 'doc'
 86   
    * have to be set separately before the dialog is operable.</p>
 87   
    *
 88   
    * @see javax.swing.JEditorPane
 89   
    * @see javax.swing.text.Document
 90   
    * @see java.awt.Frame
 91   
    */
 92  0
   public FindReplaceDialog() {
 93  0
     try {
 94  0
       jbInit();
 95  0
       initDialogContents();
 96  0
       pack();
 97   
     }
 98   
     catch(Exception e) {
 99  0
       e.printStackTrace();
 100   
     }
 101   
   }
 102   
 
 103   
   /**
 104   
    * Construct a <code>FindReplaceDialog</code>.
 105   
    *
 106   
    * <p>Shows the dialog window modal, packed and centered over the owning
 107   
    * <code>Frame</code> after construction.</p>
 108   
    *
 109   
    * <p>Using this constructor implies the dialog shall be used in mode
 110   
    * MODE_DOCUMENT</p>
 111   
    *
 112   
    * @param owner  the <code>Frame</code> that owns this dialog
 113   
    * @param editor  <code>JEditorPane</code> displaying the
 114   
    *                    <code>Document</code> to seach in
 115   
    *
 116   
    * @see javax.swing.JEditorPane
 117   
    * @see javax.swing.text.Document
 118   
    * @see java.awt.Frame
 119   
    */
 120  0
   public FindReplaceDialog(Frame owner, JEditorPane editor)
 121   
   {
 122  0
     setEditor(editor);
 123  0
     setMode(MODE_DOCUMENT);
 124  0
     try {
 125  0
       jbInit();
 126  0
       initDialogContents();
 127  0
       centerDialog(owner);
 128  0
       pack();
 129  0
       setVisible(true);
 130   
     }
 131   
     catch(Exception e) {
 132  0
       e.printStackTrace();
 133   
     }
 134   
   }
 135   
 
 136   
   /**
 137   
    * Construct a <code>FindReplaceDialog</code>.
 138   
    *
 139   
    * <p>Shows the dialog window modal, packed and centered over the owning
 140   
    * <code>Frame</code> after construction.</p>
 141   
    *
 142   
    * <p>Using this constructor implies the dialog shall be used in mode
 143   
    * MODE_PROJECT</p>
 144   
    *
 145   
    * @param owner  the <code>Frame</code> that owns this dialog
 146   
    * @param editor  <code>JEditorPane</code> displaying the
 147   
    *                    <code>Document</code> to seach in
 148   
    * @param listener  listener for handling FindReplaceEvents
 149   
    *
 150   
    * @see javax.swing.JEditorPane
 151   
    * @see javax.swing.text.Document
 152   
    * @see java.awt.Frame
 153   
    */
 154  2
   public FindReplaceDialog(Frame owner, JEditorPane editor,
 155   
               FindReplaceListener listener)
 156   
   {
 157  2
     setEditor(editor);
 158  2
     setMode(MODE_PROJECT);
 159  2
     addFindReplaceListener(listener);
 160  2
     try {
 161  2
       jbInit();
 162  2
       initDialogContents();
 163  2
       centerDialog(owner);
 164  2
       pack();
 165  2
       setVisible(true);
 166   
     }
 167   
     catch(Exception e) {
 168  0
       e.printStackTrace();
 169   
     }
 170   
   }
 171   
 
 172   
   /* --------- Constructor(s) end ------------- */
 173   
 
 174   
   /* --------- Event handling start ------------- */
 175   
 
 176   
   /**
 177   
    * add an event listener to this dialog.
 178   
    *
 179   
    * @param  listener  the event listener to add
 180   
    */
 181  2
   public void addFindReplaceListener(FindReplaceListener listener) {
 182  2
     listeners.addElement(listener);
 183   
   }
 184   
 
 185   
   /**
 186   
    * remove an event listener from this dialog.
 187   
    *
 188   
    * @param  listener  the event listener to remove
 189   
    */
 190  0
   public void removeFindReplaceListener(FindReplaceListener listener) {
 191  0
     listeners.removeElement(listener);
 192   
   }
 193   
 
 194   
   /**
 195   
    * notify listeners interested in this event that it occurred
 196   
    *
 197   
    * @param  node  the node, that is affected by the event
 198   
    */
 199  0
   private void fireGetNextDocument() {
 200  0
     Enumeration listenerList = listeners.elements();
 201  0
     while(listenerList.hasMoreElements()) {
 202  0
       ((FindReplaceListener) listenerList.nextElement()).getNextDocument(
 203   
                                           new FindReplaceEvent(this));
 204   
     }
 205   
   }
 206   
 
 207   
   /**
 208   
    * notify listeners interested in this event that it occurred
 209   
    *
 210   
    * @param  node  the node, that is affected by the event
 211   
    */
 212  0
   private void fireGetFirstDocument() {
 213  0
     Enumeration listenerList = listeners.elements();
 214  0
     while(listenerList.hasMoreElements()) {
 215  0
       ((FindReplaceListener) listenerList.nextElement()).getFirstDocument(
 216   
                                           new FindReplaceEvent(this));
 217   
     }
 218   
   }
 219   
 
 220   
   /**
 221   
    * notify listeners interested in this event that it occurred
 222   
    *
 223   
    * @param  node  the node, that is affected by the event
 224   
    */
 225  0
   private void fireFindReplaceTerminated() {
 226  0
     Enumeration listenerList = listeners.elements();
 227  0
     while(listenerList.hasMoreElements()) {
 228  0
       ((FindReplaceListener) listenerList.nextElement()).findReplaceTerminated(
 229   
                                           new FindReplaceEvent(this));
 230   
     }
 231   
   }
 232   
 
 233   
   /**
 234   
    * Resume the current operation after a getFirstDocument or getNextDocument
 235   
    * event was fired
 236   
    */
 237  0
   public void resumeOperation() {
 238  0
     this.doc = editor.getDocument();
 239  0
     findInProgress = false;
 240  0
     initFind();
 241  0
     switch(operation) {
 242  0
       case OP_FIND:
 243  0
         find();
 244  0
         break;
 245  0
       case OP_REPLACE:
 246  0
         replace();
 247  0
         break;
 248   
     }
 249   
   }
 250   
 
 251   
   /**
 252   
    * Terminate the current operation
 253   
    */
 254  1
   public void terminateOperation() {
 255  1
     switch(operation) {
 256  0
       case OP_FIND:
 257  0
         message(FrmMain.dynRes.getResourceString(FrmMain.resources, "noMoreOccurrencesFound"));
 258  0
         toggleState(STATE_UNLOCKED);
 259  0
         jbtnReplace.setEnabled(true);
 260  0
         break;
 261  1
       case OP_REPLACE:
 262  1
         switch(replaceChoice) {
 263  1
           case RO_YES:
 264  0
           case RO_NO:
 265  1
             message(FrmMain.dynRes.getResourceString(FrmMain.resources, "noMoreOccurrencesFound"));
 266  0
             break;
 267  0
           case RO_ALL:
 268  0
             message(FrmMain.dynRes.getResourceString(FrmMain.resources, "allOccurrencesReplaced"));
 269  0
             break;
 270   
         }
 271  0
         toggleState(STATE_UNLOCKED);
 272  0
         show();
 273  0
         break;
 274   
     }
 275  0
     operation = OP_NONE;
 276  0
     fireFindReplaceTerminated();
 277   
   }
 278   
 
 279   
   /**
 280   
    * perform a find, when button 'find next' is pressed
 281   
    */
 282  0
   private void jbtnFindNext_actionPerformed(ActionEvent e) {
 283  0
     operation = OP_FIND;
 284  0
     jbtnReplace.setEnabled(false);
 285  0
     if( mode == MODE_PROJECT &&
 286   
         jcbProject.isSelected() &&
 287   
         listeners.size() > 0 &&
 288   
         !findInProgress)
 289   
     {
 290  0
       fireGetFirstDocument();
 291   
     }
 292   
     else {
 293  0
       initFind();
 294  0
       find();
 295   
     }
 296   
   }
 297   
 
 298   
   /**
 299   
    * perform a replace, when button 'replace' is pressed
 300   
    */
 301  2
   private void jbtnReplace_actionPerformed(ActionEvent e) {
 302  2
     operation = OP_REPLACE;
 303  2
     replaceChoice = RO_YES;
 304  2
     hide();
 305  2
     if( mode == MODE_PROJECT &&
 306   
         jcbProject.isSelected() &&
 307   
         listeners.size() > 0 &&
 308   
         !findInProgress)
 309   
     {
 310  0
       fireGetFirstDocument();
 311   
     }
 312   
     else {
 313  2
       initFind();
 314  2
       replace();
 315   
     }
 316   
   }
 317   
 
 318   
   /**
 319   
    * Cancels the current find operation and switches the dialog back to
 320   
    * normal.
 321   
    */
 322  0
   private void jbtnCancel_actionPerformed(ActionEvent e) {
 323  0
     toggleState(STATE_UNLOCKED);
 324  0
     jbtnReplace.setEnabled(true);
 325   
   }
 326   
 
 327   
   /**
 328   
    * When Close is pressed, store the pressed button in the result
 329   
    * of this dialog and dispose the dialog.
 330   
    */
 331  0
   private void jbtnClose_actionPerformed(ActionEvent e) {
 332  0
     result = JOptionPane.OK_OPTION;
 333  0
     dispose();
 334   
   }
 335   
 
 336   
   /* --------- Event handling end ------------- */
 337   
 
 338   
   /* --------- Getters and setters start ------------- */
 339   
 
 340   
   /**
 341   
    * Set the JEditorPane holding the document to be searched
 342   
    *
 343   
    * @param editor  the JEditorPane holding the document to be searched
 344   
    *
 345   
    * @see javax.swing.JEditorPane
 346   
    */
 347  2
   public void setEditor(JEditorPane editor) {
 348  2
     this.editor = editor;
 349  2
     this.doc = editor.getDocument();
 350   
   }
 351   
 
 352   
   /**
 353   
    * Set the mode.
 354   
    *
 355   
    * <p>Switches between</p>
 356   
    * <ul>
 357   
    * <li>MODE_DOCUMENT: only the document currently viewed in the editor can be
 358   
    *    searched</li>
 359   
    * <li>MODE_PROJECT: An additional check box allows to choose, whether or not
 360   
    *    the user likes to search a whole group of documents.</li>
 361   
    * </ul>
 362   
    *
 363   
    * @param mode  one of MODE_DOCUMENT and MODE_PROJECT
 364   
    */
 365  2
   public void setMode(int mode) {
 366  2
     this.mode = mode;
 367  2
     if(mode == MODE_PROJECT) {
 368  2
       jcbProject.setVisible(true);
 369   
     }
 370   
     else {
 371  0
       jcbProject.setVisible(false);
 372   
     }
 373   
   }
 374   
 
 375   
   /* --------- Getters and setters end ------------- */
 376   
 
 377   
   /* --------- Find implementation start ------ */
 378   
 
 379   
   /**
 380   
    * Initialize a find operation by reading all relevant settings and
 381   
    * locking the dialog window.
 382   
    */
 383  2
   private void initFind() {
 384  2
     if(!findInProgress) {
 385  2
       try {
 386  2
         searchText = doc.getText(0, doc.getLength());
 387   
       }
 388   
       catch(Exception e) {
 389  0
         e.printStackTrace();
 390   
       }
 391  2
       phrase = jtfPhrase.getText();
 392  2
       newPhrase = jtfReplace.getText();
 393  2
       replaceDiff = newPhrase.length() - phrase.length();
 394  2
       offset = 0;
 395  2
       if(!jcbMatchCase.isSelected()) {
 396  2
         phrase = phrase.toLowerCase();
 397  2
         searchText = searchText.toLowerCase();
 398   
       }
 399  2
       if(jcbStartOnTop.isSelected()) {
 400  2
         if(jrbUp.isSelected()) {
 401  0
           lastPos = doc.getLength();
 402   
         }
 403   
         else {
 404  2
           lastPos = 0;
 405   
         }
 406   
       }
 407   
       else {
 408  0
         lastPos = editor.getSelectionStart();
 409   
       }
 410  2
       toggleState(STATE_LOCKED);
 411   
     }
 412   
   }
 413   
 
 414   
   /**
 415   
    * Initiate a find or find next operation, whatever applies. If no (more)
 416   
    * hits are found, a message is displayed and the dialog is unlocked for a
 417   
    * new search operation.
 418   
    */
 419  0
   private void find() {
 420  0
     if(!doFind()) {
 421  0
       if( mode == MODE_PROJECT &&
 422   
           jcbProject.isSelected() &&
 423   
           listeners.size() > 0)
 424   
       {
 425  0
         fireGetNextDocument();
 426   
       }
 427   
       else {
 428  0
         terminateOperation();
 429   
       }
 430   
     }
 431   
   }
 432   
 
 433   
   /**
 434   
    * Look for the next occurrence of the search phrase either as whole word
 435   
    * or as part of a word, depending on the current dialog setting.
 436   
    *
 437   
    * <p>If the phrase is found (again), its position is 'remembered' for a
 438   
    * possible findNext and its postion is highlighted in the underlying
 439   
    * <code>JEditorPane</code>.
 440   
    *
 441   
    * @return  true, if the phrase was found (again), false if not
 442   
    *
 443   
    * @see javax.swing.JEditorPane
 444   
    */
 445  2
   private boolean doFind() {
 446  2
     boolean found = false;
 447  2
     int start = findNext();
 448  2
     if(jcbWholeWords.isSelected()) {
 449  0
       start = findWholeWords(start);
 450   
     }
 451  2
     if(start > 0) {
 452  1
       lastPos = start;
 453  1
       if(jrbDown.isSelected()) {
 454  1
         start += offset;
 455   
       }
 456  1
       editor.select(start, start + phrase.length());
 457  1
       found = true;
 458   
     }
 459  2
     return found;
 460   
   }
 461   
 
 462   
   /**
 463   
    * Find the next occurrence of a searched phrase from the last position
 464   
    * either up or down.
 465   
    *
 466   
    * @return the start position of the next occurrence or
 467   
    *                          0 if no more hits were found
 468   
    */
 469  2
   private int findNext() {
 470  2
     int start;
 471  2
     if(jrbUp.isSelected()) {
 472  0
       if(lastPos < doc.getLength()) {
 473  0
         start = searchText.lastIndexOf(phrase, lastPos - 1);
 474   
       }
 475   
       else {
 476  0
         start = searchText.lastIndexOf(phrase, lastPos);
 477   
       }
 478   
     }
 479   
     else {
 480  2
       if(lastPos > 0) {
 481  0
         start = searchText.indexOf(phrase, lastPos + phrase.length());
 482   
       }
 483   
       else {
 484  2
         start = searchText.indexOf(phrase, lastPos);
 485   
       }
 486   
     }
 487  2
     return start;
 488   
   }
 489   
 
 490   
   /**
 491   
    * Find the next whole word occurrence of the searched phrase from
 492   
    * a given position.
 493   
    *
 494   
    * @param start  the position to start the search at
 495   
    *
 496   
    * @return the start position of the next occurrence or
 497   
    *                          0 if no more hits were found
 498   
    */
 499  0
   private int findWholeWords(int start) {
 500  0
     while(  (start > 0) &&
 501   
             ((!isSeparator(searchText.charAt(start-1))) ||
 502   
             (!isSeparator(searchText.charAt(start + phrase.length())))))
 503   
     {
 504  0
       lastPos = start;
 505  0
       start = findNext();
 506   
     }
 507  0
     return start;
 508   
   }
 509   
 
 510   
   /* ----------- Find implementation end ------- */
 511   
 
 512   
   /* ----------- Replace implementation start ------- */
 513   
 
 514   
   /**
 515   
    * Initiate a replace operation. If no (more)
 516   
    * hits are found, a message is displayed and the dialog is unlocked for a
 517   
    * new search operation.
 518   
    */
 519  2
   private void replace() {
 520  2
     while(replaceChoice != RO_DONE && doFind()) {
 521  1
       if(replaceChoice != RO_ALL) {
 522  1
         replaceChoice = getReplaceChoice();
 523   
       }
 524  0
       switch(replaceChoice) {
 525  0
         case RO_YES:
 526  0
           replaceOne();
 527  0
           break;
 528  0
         case RO_ALL:
 529  0
           replaceOne();
 530  0
           while(doFind()) {
 531  0
             replaceOne();
 532   
           }
 533  0
           break;
 534   
       }
 535   
     }
 536  1
     if( mode == MODE_PROJECT &&
 537   
         jcbProject.isSelected() &&
 538   
         listeners.size() > 0)
 539   
     {
 540  0
       switch(replaceChoice) {
 541  0
         case RO_YES:
 542  0
         case RO_NO:
 543  0
         case RO_ALL:
 544  0
           fireGetNextDocument();
 545  0
           break;
 546  0
         case RO_DONE:
 547  0
           terminateOperation();
 548  0
           break;
 549   
       }
 550   
     }
 551   
     else {
 552  1
       terminateOperation();
 553   
     }
 554   
   }
 555   
 
 556   
   /**
 557   
    * Show an option window asking the user for a decision about what to
 558   
    * do with the found occurrence during a replace operation.
 559   
    *
 560   
    * @return the chosen option, one of RO_YES, RO_NO, RO_DONE and RO_ALL
 561   
    */
 562  1
   private int getReplaceChoice() {
 563  1
     String msg = FrmMain.dynRes.getResourceString(FrmMain.resources, "replaceThisQuery") + " '" + phrase + "'?";
 564  1
     return JOptionPane.showOptionDialog(
 565   
                 this,
 566   
                 msg,
 567   
                 FrmMain.dynRes.getResourceString(FrmMain.resources, "findReplaceDialogTitle"),
 568   
                 JOptionPane.YES_NO_CANCEL_OPTION,
 569   
                 JOptionPane.QUESTION_MESSAGE,
 570   
                 null,
 571   
                 replaceOptions,
 572   
                 null);
 573   
   }
 574   
 
 575   
   /**
 576   
    * Replace the currently selected occurrence of the search phrase
 577   
    */
 578  0
   private void replaceOne() {
 579  0
     editor.replaceSelection(newPhrase);
 580  0
     offset += replaceDiff;
 581   
   }
 582   
 
 583   
   /* ----------- Replace implementation end ------- */
 584   
 
 585   
   /* ----------- Helper methods start ------- */
 586   
 
 587   
   /**
 588   
    * Set dialog components to their inital state
 589   
    */
 590  2
   private void initDialogContents() {
 591  2
     jbtnCancel.setEnabled(false);
 592  2
     jrbUp.setSelected(false);
 593  2
     jrbDown.setSelected(true);
 594  2
     jcbWholeWords.setSelected(false);
 595  2
     jcbMatchCase.setSelected(false);
 596  2
     jcbStartOnTop.setSelected(true);
 597  2
     jcbProject.setSelected(false);
 598  2
     jtfPhrase.setText("");
 599  2
     jtfReplace.setText("");
 600   
   }
 601   
 
 602   
   /**
 603   
    * Center this dialog window relative to its owning <code>Frame</code>.
 604   
    *
 605   
    * @param owner  <code>Frame</code> owning this dialog
 606   
    *
 607   
    * @see java.awt.Frame
 608   
    */
 609  2
   public void centerDialog(Frame owner) {
 610  2
     Dimension dlgSize = getPreferredSize();
 611  2
     Dimension frmSize = owner.getSize();
 612  2
     Point loc = owner.getLocation();
 613  2
     setLocation((frmSize.width - dlgSize.width) / 2 + loc.x,
 614   
                             (frmSize.height - dlgSize.height) / 2 + loc.y);
 615   
   }
 616   
 
 617   
   /**
 618   
    * Toggle the state of the dialog window.
 619   
    *
 620   
    * <p>The state of the dialog is either unlocked (no find in progress) or
 621   
    * locked (find in progress).</p>
 622   
    *
 623   
    * @param unlocked  one of FindReplaceDialog.STATE_LOCKED and
 624   
    *      FindReplaceDialog.STATE_UNLOCKED
 625   
    */
 626  2
   private void toggleState(boolean unlocked) {
 627  2
     jbtnCancel.setEnabled(!unlocked);
 628  2
     jbtnClose.setEnabled(unlocked);
 629  2
     jtfPhrase.setEnabled(unlocked);
 630  2
     jLabel3.setEnabled(unlocked);
 631  2
     jLabel4.setEnabled(unlocked);
 632  2
     jcbWholeWords.setEnabled(unlocked);
 633  2
     jcbMatchCase.setEnabled(unlocked);
 634  2
     jcbStartOnTop.setEnabled(unlocked);
 635  2
     jrbUp.setEnabled(unlocked);
 636  2
     jrbDown.setEnabled(unlocked);
 637  2
     jcbProject.setEnabled(unlocked);
 638  2
     findInProgress = !unlocked;
 639   
   }
 640   
 
 641   
   /**
 642   
    * method for determining whether or not a character is a
 643   
    * word separator.
 644   
    */
 645  0
   private boolean isSeparator(char ch) {
 646  0
     int i = 0;
 647  0
     while((i<WORD_SEPARATORS.length) && (ch != WORD_SEPARATORS[i])) {
 648  0
       i++;
 649   
     }
 650  0
     return (i<WORD_SEPARATORS.length);
 651   
   }
 652   
 
 653   
   /**
 654   
    * Show an information message
 655   
    */
 656  1
   private void message(String msgText) {
 657  1
     JOptionPane.showMessageDialog(
 658   
                 this,
 659   
                 msgText,
 660   
                 FrmMain.dynRes.getResourceString(FrmMain.resources, "findReplaceDialogTitle"),
 661   
                 JOptionPane.INFORMATION_MESSAGE);
 662   
   }
 663   
 
 664   
   /* ----------- Helper methods end ------- */
 665   
 
 666   
   /** GUI builder init */
 667  2
   private void jbInit() throws Exception {
 668  2
     titledBorder1 = new TitledBorder(BorderFactory.createEtchedBorder(Color.white,new Color(142, 142, 142)),"Options");
 669  2
     ButtonGroup bgSearchDirection = new ButtonGroup();
 670  2
     jbtnFindNext.addActionListener(new java.awt.event.ActionListener() {
 671  0
       public void actionPerformed(ActionEvent e) {
 672  0
         jbtnFindNext_actionPerformed(e);
 673   
       }
 674   
     });
 675  2
     jbtnFindNext.setText(FrmMain.dynRes.getResourceString(FrmMain.resources, "findNext"));
 676  2
     jbtnFindNext.setPreferredSize(new Dimension(100, 27));
 677  2
     jbtnFindNext.setMinimumSize(new Dimension(100, 27));
 678  2
     jbtnFindNext.setMaximumSize(new Dimension(100, 27));
 679  2
     jcbStartOnTop.setText(FrmMain.dynRes.getResourceString(FrmMain.resources, "searchFromStart"));
 680  2
     jcbStartOnTop.setToolTipText("");
 681  2
     jrbDown.setText(FrmMain.dynRes.getResourceString(FrmMain.resources, "searchDown"));
 682  2
     jcbWholeWords.setText(FrmMain.dynRes.getResourceString(FrmMain.resources, "wholeWordsOnly"));
 683  2
     jpnlBtn.setLayout(gridBagLayout4);
 684  2
     jpnlOptions.setBorder(titledBorder1);
 685  2
     jpnlOptions.setLayout(gridLayout2);
 686  2
     jpnlFind.setLayout(gridBagLayout5);
 687  2
     jtfReplace.setMinimumSize(new Dimension(4, 12));
 688  2
     jtfReplace.setPreferredSize(new Dimension(59, 12));
 689  2
     jtfReplace.setText("jtfReplace");
 690  2
     jpnlMain.setLayout(gridBagLayout6);
 691  2
     jrbUp.setText(FrmMain.dynRes.getResourceString(FrmMain.resources, "searchUp"));
 692  2
     jtfPhrase.setMinimumSize(new Dimension(4, 12));
 693  2
     jtfPhrase.setPreferredSize(new Dimension(63, 12));
 694  2
     jtfPhrase.setText("jtfPhrase");
 695  2
     jcbMatchCase.setText(FrmMain.dynRes.getResourceString(FrmMain.resources, "matchCase"));
 696  2
     jLabel3.setText(FrmMain.dynRes.getResourceString(FrmMain.resources, "replaceWith"));
 697  2
     jLabel4.setText(FrmMain.dynRes.getResourceString(FrmMain.resources, "textToFind"));
 698  2
     jbtnClose.setMaximumSize(new Dimension(100, 27));
 699  2
     jbtnClose.setMinimumSize(new Dimension(100, 27));
 700  2
     jbtnClose.setPreferredSize(new Dimension(100, 27));
 701  2
     jbtnClose.setText(FrmMain.dynRes.getResourceString(FrmMain.resources, "closeBtnName"));
 702  2
     jbtnClose.addActionListener(new java.awt.event.ActionListener() {
 703  0
       public void actionPerformed(ActionEvent e) {
 704  0
         jbtnClose_actionPerformed(e);
 705   
       }
 706   
     });
 707  2
     gridLayout2.setRows(4);
 708  2
     gridLayout2.setColumns(2);
 709  2
     this.setModal(true);
 710  2
     this.setTitle(FrmMain.dynRes.getResourceString(FrmMain.resources, "findReplaceDialogTitle"));
 711  2
     jbtnReplace.setMaximumSize(new Dimension(100, 27));
 712  2
     jbtnReplace.setMinimumSize(new Dimension(100, 27));
 713  2
     jbtnReplace.setPreferredSize(new Dimension(100, 27));
 714  2
     jbtnReplace.setText(FrmMain.dynRes.getResourceString(FrmMain.resources, "replace"));
 715  2
     jbtnReplace.addActionListener(new java.awt.event.ActionListener() {
 716  2
       public void actionPerformed(ActionEvent e) {
 717  2
         jbtnReplace_actionPerformed(e);
 718   
       }
 719   
     });
 720  2
     jbtnCancel.setMaximumSize(new Dimension(100, 27));
 721  2
     jbtnCancel.setMinimumSize(new Dimension(100, 27));
 722  2
     jbtnCancel.setPreferredSize(new Dimension(100, 27));
 723  2
     jbtnCancel.setText(FrmMain.dynRes.getResourceString(FrmMain.resources, "cancelBtnName"));
 724  2
     jbtnCancel.addActionListener(new java.awt.event.ActionListener() {
 725  0
       public void actionPerformed(ActionEvent e) {
 726  0
         jbtnCancel_actionPerformed(e);
 727   
       }
 728   
     });
 729  2
     jcbUnused.setText("jcbUnused");
 730  2
     jcbUnused.setVisible(false);
 731  2
     jcbProject.setText(FrmMain.dynRes.getResourceString(FrmMain.resources, "searchWholeProject"));
 732  2
     this.getContentPane().add(jpnlMain, BorderLayout.NORTH);
 733  2
     jpnlBtn.add(jbtnFindNext,   new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
 734   
             ,GridBagConstraints.NORTH, GridBagConstraints.NONE, new Insets(4, 4, 0, 4), 0, 0));
 735  2
     jpnlBtn.add(jbtnClose,    new GridBagConstraints(0, 3, 1, 1, 0.0, 0.0
 736   
             ,GridBagConstraints.NORTH, GridBagConstraints.NONE, new Insets(0, 4, 4, 4), 0, 0));
 737  2
     jpnlBtn.add(jbtnReplace,    new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0
 738   
             ,GridBagConstraints.NORTH, GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0));
 739  2
     jpnlBtn.add(jbtnCancel,  new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0
 740   
             ,GridBagConstraints.NORTH, GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0));
 741  2
     jpnlMain.add(jpnlFind, new GridBagConstraints(0, 0, 1, 1, 1.0, 1.0
 742   
             ,GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(4, 4, 4, 4), 0, 0));
 743  2
     jpnlMain.add(jpnlBtn,  new GridBagConstraints(1, 0, 1, 2, 1.0, 1.0
 744   
             ,GridBagConstraints.NORTHEAST, GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0));
 745  2
     jpnlFind.add(jtfPhrase,  new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0
 746   
             ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(4, 4, 4, 4), 0, 12));
 747  2
     jpnlFind.add(jLabel4, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0
 748   
             ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0));
 749  2
     jpnlFind.add(jtfReplace,       new GridBagConstraints(1, 1, 1, 1, 0.0, 0.0
 750   
             ,GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(4, 4, 4, 4), 0, 12));
 751  2
     jpnlFind.add(jLabel3, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0
 752   
             ,GridBagConstraints.EAST, GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0));
 753  2
     jpnlMain.add(jpnlOptions,   new GridBagConstraints(0, 1, 1, 1, 1.0, 1.0
 754   
             ,GridBagConstraints.SOUTHWEST, GridBagConstraints.NONE, new Insets(4, 4, 4, 4), 0, 0));
 755  2
     jpnlOptions.add(jcbWholeWords, null);
 756  2
     jpnlOptions.add(jrbUp, null);
 757  2
     jpnlOptions.add(jcbMatchCase, null);
 758  2
     jpnlOptions.add(jrbDown, null);
 759  2
     jpnlOptions.add(jcbStartOnTop, null);
 760  2
     jpnlOptions.add(jcbUnused, null);
 761  2
     jpnlOptions.add(jcbProject, null);
 762  2
     bgSearchDirection.add(jrbUp);
 763  2
     bgSearchDirection.add(jrbDown);
 764   
   }
 765   
 
 766   
   /* ----------------- class fields ------------------------------ */
 767   
 
 768   
   /** result value for this dialog */
 769   
   private int result;
 770   
 
 771   
   /** mode of dialog */
 772   
   private int mode;
 773   
 
 774   
   /** JEditorPane containing the document to search in */
 775   
   private JEditorPane editor;
 776   
 
 777   
   /** Document to search in */
 778   
   private Document doc;
 779   
 
 780   
   /** search text from the document */
 781   
   private String searchText;
 782   
 
 783   
   /** search phrase to find */
 784   
   private String phrase;
 785   
 
 786   
   /** new phrase to replace the searched phrase with */
 787   
   private String newPhrase;
 788   
 
 789   
   /** last start position, the search phrase was found at in the document */
 790   
   private int lastPos;
 791   
 
 792   
   /** two fields to correct position differences during replace operations */
 793   
   private int offset;
 794   
   private int replaceDiff;
 795   
 
 796   
   /** indicates if a find is already in progress */
 797   
   private boolean findInProgress = false;
 798   
 
 799   
   /** indicates the current operation */
 800   
   private int operation;
 801   
 
 802   
   /** choice of replace operation */
 803   
   private int replaceChoice;
 804   
 
 805   
   /** the listeners for FindReplaceEvents */
 806   
   private Vector listeners = new Vector(0);
 807   
 
 808   
   /** separators for whole words only search */
 809   
   private static final char[] WORD_SEPARATORS = {' ', '\t', '\n',
 810   
       '\r', '\f', '.', ',', ':', '-', '(', ')', '[', ']', '{',
 811   
       '}', '<', '>', '/', '|', '\\', '\'', '\"'};
 812   
 
 813   
   /** options for replacing */
 814   
   private static final Object[] replaceOptions = {
 815   
       FrmMain.dynRes.getResourceString(FrmMain.resources, "replaceYes"),
 816   
       FrmMain.dynRes.getResourceString(FrmMain.resources, "replaceNo"),
 817   
       FrmMain.dynRes.getResourceString(FrmMain.resources, "replaceAll"),
 818   
       FrmMain.dynRes.getResourceString(FrmMain.resources, "replaceDone")
 819   
   };
 820   
 
 821   
   /* Constants for method toggleState */
 822   
   public static final boolean STATE_LOCKED = false;
 823   
   public static final boolean STATE_UNLOCKED = true;
 824   
 
 825   
   /* Constants for replaceOptions */
 826   
   public static final int RO_YES = 0;
 827   
   public static final int RO_NO = 1;
 828   
   public static final int RO_ALL = 2;
 829   
   public static final int RO_DONE = 3;
 830   
 
 831   
   /* Constants for dialog mode */
 832   
   public static final int MODE_DOCUMENT = 1;
 833   
   public static final int MODE_PROJECT = 2;
 834   
 
 835   
   /* Constants for operation */
 836   
   public static final int OP_NONE = 0;
 837   
   public static final int OP_FIND = 1;
 838   
   public static final int OP_REPLACE = 2;
 839   
 
 840   
   /* ---- GUI elements start ---------*/
 841   
 
 842   
   private TitledBorder titledBorder1;
 843   
   private JButton jbtnFindNext = new JButton();
 844   
   private JCheckBox jcbStartOnTop = new JCheckBox();
 845   
   private JRadioButton jrbDown = new JRadioButton();
 846   
   private JCheckBox jcbWholeWords = new JCheckBox();
 847   
   private JPanel jpnlBtn = new JPanel();
 848   
   private JPanel jpnlOptions = new JPanel();
 849   
   private JPanel jpnlFind = new JPanel();
 850   
   private JTextField jtfReplace = new JTextField();
 851   
   private JPanel jpnlMain = new JPanel();
 852   
   private JRadioButton jrbUp = new JRadioButton();
 853   
   private JTextField jtfPhrase = new JTextField();
 854   
   private JCheckBox jcbMatchCase = new JCheckBox();
 855   
   private JLabel jLabel3 = new JLabel();
 856   
   private JLabel jLabel4 = new JLabel();
 857   
   private GridBagLayout gridBagLayout4 = new GridBagLayout();
 858   
   private GridBagLayout gridBagLayout5 = new GridBagLayout();
 859   
   private JButton jbtnClose = new JButton();
 860   
   private GridBagLayout gridBagLayout6 = new GridBagLayout();
 861   
   private GridLayout gridLayout2 = new GridLayout();
 862   
   private JButton jbtnReplace = new JButton();
 863   
   private JButton jbtnCancel = new JButton();
 864   
   private JCheckBox jcbUnused = new JCheckBox();
 865   
   private JCheckBox jcbProject = new JCheckBox();
 866   
 
 867   
   /* ---- GUI elements end ---------*/
 868   
 }