home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / listpm4.zip / source / list.cpp < prev    next >
C/C++ Source or Header  |  1998-04-22  |  26KB  |  774 lines

  1. /*
  2.     listPM list files under Presentation Manager. Uses Open Class Libarary.
  3.     Copyright (C) 1998  Paul Elliott
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18.  
  19.     Paul Elliott
  20.     11900 Metric Blvd #J-181
  21.     Austin Tx 78758-3117
  22.     pelliott@io.com
  23. */
  24. #include "listpm.h"            // constants for resourse libarary.
  25.                                // do not edit listpm.h, but use URE to modify.
  26.  
  27. #include "list.hpp"            // List window defined.
  28.  
  29. #include "glbsize.hpp"         // How to store ISize externally.
  30. #include "glbfont.hpp"         // How to store IFont Externally.
  31. #include "glbwrap.hpp"         // How to save word wrap options.
  32. #include "listthrd.hpp"        // List threads defined
  33.  
  34.  
  35. #include "OneOf.hpp"           // define one of a kind of object at runtime.
  36. #include "IsDir.hpp"           // is file a directory?
  37.  
  38.  
  39. #include <iapp.hpp>
  40.  
  41. // manipulate files.
  42. #include <iostream.h>
  43. #include <iomanip.h>
  44. #include <fstream.h>
  45. #include "switch.hpp"
  46.  
  47.  
  48.  
  49.  
  50. // Global statics interfacing external storage.
  51. // we want One of these objects, but they must be initializied
  52. // after application argc argv are set.
  53. static OneOf<SizeStore> resizer;                 // source of ISize
  54. static OneOf<ExternalFont> font_source;          // source of IFont s
  55. static OneOf<ExternalWrap> wrap_source;          // source of wrap booleans.
  56.  
  57. // main window consturctor.
  58. // mostly constructed via ctor.
  59. ListFrame::ListFrame( const IString file) :
  60.                   file_displayed(file),                        //save title
  61.                   // frame window from resource id & style
  62.                   IFrameWindow( WIN_UICLLISTER ,
  63.  
  64.                       IFrameWindow::defaultStyle() |          // default style
  65.                       IFrameWindow::shellPosition  |          // wps positions
  66.                       IFrameWindow::accelerator    |          // accelerator
  67.                       IFrameWindow::border         |          // and border
  68.                       IFrameWindow::menuBar        |          // and menu
  69.                       IFrameWindow::minimizedIcon  |          // icon for
  70.                                                               // minimization
  71.                       IFrameWindow::sizingBorder   |          // border sizing
  72.                       IFrameWindow::systemMenu     |          // system menu
  73.                       IFrameWindow::titleBar       ),         // with title bar
  74.  
  75.  
  76.  
  77.                   acc ( WIN_UICLLISTER , this),               // accelerator
  78.                   info(this),                                 // info area
  79.  
  80.                   // multiline edit field
  81.                   mle ( MLE_TEXT ,this , this, IRectangle(),
  82.                     (IMultiLineEdit::defaultStyle()           // default style
  83.                     | IMultiLineEdit::readOnly                // readonly
  84.                     | IMultiLineEdit::verticalScroll          // scroll vert
  85.                     | IMultiLineEdit::horizontalScroll ) ),   // edit client
  86.                   title( this, STR_TITLE ),                   // title bar
  87.                   help(ID_HELPTABLE,this),                    // attach help win
  88.                   search_dialog( *this , help ),              // search dialog.
  89.                   win_thread(*this,IDM_SEARCHNOT,mle,info)    // window
  90.                                                               // threader.
  91.  
  92. {   // code for constructor
  93.     ICommandHandler::handleEventsFor(this);       // attach command handler.
  94.     IMenuHandler::handleEventsFor(this);          // attach menu handler.
  95.     IResizeHandler::handleEventsFor(this);        // attach resize handler.
  96.  
  97.     SizeStore& l_resizer = resizer;               // get stoed window size
  98.     if (l_resizer.sizeExternal() )                // if an ISize is external
  99.     {
  100.         // get external size
  101.         ISize external_size( l_resizer );
  102.  
  103.         ISize current_size = external_size;
  104.  
  105.         // set window to that size
  106.         sizeTo(current_size);
  107.  
  108.         // code to insure that the window is positioned on the desk
  109.         // top if possible.
  110.  
  111.         // get size of desktop.
  112.         ISize desk_size = IWindow::desktopWindow()->size();
  113.  
  114.         // get position currently proposed.
  115.         IPoint current_position = position();
  116.  
  117.         // assume current position good.
  118.         IPoint new_position = current_position;
  119.  
  120.         if (                            // if positioning is possible!
  121.            // right of window is off screen
  122.            ( current_position.x() + current_size.width() >
  123.                desk_size.width() ) &&
  124.  
  125.            // the whole window will fit on the screen
  126.            ( current_size.width() <= desk_size.width() )
  127.            )
  128.          {
  129.             // degree of freedom in positioning.
  130.             int x_slop = desk_size.width() - current_size.width();
  131.  
  132.             // a plausible pull back from against the right wall.
  133.             int x_pullback = desk_size.width() / 10;
  134.             if ( x_pullback > x_slop) x_pullback = x_slop;
  135.  
  136.             // reanomize the pullback.
  137.             x_pullback *= float(rand()) / float(RAND_MAX) ;
  138.  
  139.             // new position is against right wall pulled back by random amount.
  140.             new_position.setX( x_slop - x_pullback );
  141.          };
  142.  
  143.         // this code is same as above except for doing y co-ordinate.
  144.         if (
  145.            // bottom of window is off screen
  146.            ( current_position.y() + current_size.height() >
  147.               desk_size.height() ) &&
  148.  
  149.            // the whole window will fit on the screen
  150.            ( current_size.height() <= desk_size.height() )
  151.            )
  152.         {
  153.             int y_slop = desk_size.height() - current_size.height();
  154.             int y_pullback = desk_size.height() / 10;
  155.             if ( y_pullback > y_slop) y_pullback = y_slop;
  156.             y_pullback *= float(rand()) / float(RAND_MAX) ;
  157.             new_position.setY( y_slop - y_pullback );
  158.         };
  159.  
  160.         // if we have decided to move the window, move it.
  161.         if ( new_position != current_position) moveTo( new_position );
  162.     };
  163.  
  164.     // if font is stored.
  165.     ExternalFont& l_font_source = font_source;
  166.     if ( l_font_source.FontExistsExternally() )
  167.     {
  168.         // then set the stored font.
  169.         mle.setFont( l_font_source );
  170.     };
  171.  
  172.     Boolean word_wrap = false;                  // assume no word wrap
  173.  
  174.     // if WW option stored.
  175.     ExternalWrap& l_wrap_source = wrap_source;
  176.     if ( l_wrap_source.wrapExternal() )
  177.     {
  178.          word_wrap = l_wrap_source;             // get WW option.
  179.     };
  180.     mle.enableWordWrap(word_wrap);              // set WW option into
  181.                                                 // edit client.
  182.  
  183.  
  184.     info.setText(file);                           // set info displayed
  185.                                                   // in info area
  186.     info.setInactiveText(file);                   // ditto, inactive
  187.     setClient( &mle );                            // set edit window as client
  188.  
  189.     help.addLibraries("listpm.hlp");              // library to use for help
  190.     help.setTitle(STR_EXENAME);                   // title of help library.
  191.     IHelpHandler::handleEventsFor(this);          // help handler.
  192.  
  193.  
  194.     // if requested file is accessable
  195.     if (file.length() != 0)
  196.     {
  197.       if ( access(file,04) )
  198.       {
  199.         // if file is not accesable, complain bitterly and leave.
  200.         mle.setFocus();
  201.         show();
  202.         IMessageBox ( this )
  203.          .show(ERR_NOTREAD,IMessageBox::information);
  204.       }
  205.       else
  206.       {
  207.         // if accessable, load into client window.
  208.         import( file);
  209.       };
  210.     }
  211.     else
  212.     {
  213.       while( cin.good() )
  214.       {
  215.         IString line = IString::lineFrom( cin );
  216.         mle.addLineAsLast( line );
  217.       };
  218.     };
  219.     setTaskList( file );
  220.  
  221.     mle.setCursorPosition ( 0 );                  // set cursor at 0,0
  222.     mle.setFocus();                               // give edit area focus, and
  223.     show();                                       // show.
  224.  
  225.  
  226. };
  227.  
  228. void ListFrame::setTaskList( const IString& myFile )
  229. {
  230.        changeSwitch(
  231.              handle() ,
  232.              ICurrentApplication::current().currentPID() ,
  233.              IApplication::current().userResourceLibrary().loadString( STR_TLPRE ) +
  234.              myFile );
  235. };
  236.  
  237.        // optional call back to user before running thread.
  238.        // to search for text.
  239. void  ListWindowThread::begin()
  240. {
  241.  
  242.          OurWindow().disable();
  243.          mle.disableUpdate();                      // freeze updates on screen
  244.  
  245.          info.setFocus();
  246.  
  247.          saved_text = info.text();
  248.  
  249.          info.setText(
  250.           IApplication::current().userResourceLibrary().loadString(STR_SEARCH)
  251.           + ": " + search_string);
  252.  
  253.  
  254.          if ( exact )                     // depends on exact case.
  255.             looked_for = search_string;
  256.          else
  257.             looked_for = IString::upperCase(search_string);
  258.          // if not exact case then always work with upcased strings.
  259.          // for both target text and examined text.
  260.  
  261.  
  262.  
  263.  
  264.  
  265.          if(forward)
  266.          {
  267.              direction_sign = direction_mult =1;
  268.              dir_search = I0String::indexOf;       // forward search fn
  269.              start_pos = 0;                        // starting pos for fn.
  270.  
  271.              limit = mle.numberOfLines() - 1 ;     // last line to look at.
  272.          }
  273.          else
  274.          {
  275.              direction_sign = -1;
  276.              direction_mult = 0;
  277.              dir_search = I0String::lastIndexOf;   // reverse search fn.
  278.              start_pos = UINT_MAX - 1;             // starting pos for fn.
  279.              limit = 0;                            // last line to look at.
  280.          };
  281.  
  282.          // the current line we are on.
  283.          current_line_no = mle.cursorLinePosition();
  284.  
  285.          // save the current position.
  286.          current_pos  = mle.cursorPosition();
  287.  
  288.          // set the cursor to the begining of this line.
  289.          mle.setCursorLinePosition( current_line_no );
  290.  
  291.          // mark beginning of this line.
  292.          current_bol  = mle.cursorPosition();
  293.  
  294.          // put cursor position back where it was.
  295.          mle.setCursorPosition(current_pos);
  296. };
  297.  
  298. // code to run on other thread.  When searching for text.
  299. void  ListWindowThread::thread()
  300. {
  301.  
  302.          // offset of our cursor in this line.
  303.          offset_within_current_line = current_pos - current_bol;
  304.  
  305.          // get text of current line.
  306.          current_line = mle.text(current_line_no);
  307.  
  308.  
  309.          // the fragment of line we are looking at.
  310.  
  311.          if ( forward )
  312.          {
  313.              // offset of the fragment within the current line
  314.              offset = offset_within_current_line;
  315.  
  316.              // get the relevant fragment of current line = the end.
  317.              line =
  318.                current_line.subString( offset_within_current_line );
  319.          }
  320.          else
  321.          {
  322.              // fragment starts at begin
  323.              offset = 0;
  324.  
  325.              // get the relevant fragment of current line = the beginning.
  326.              line =
  327.                current_line.subString( 0 , offset_within_current_line );
  328.          };
  329.  
  330.          // if !exact case work with upcased line.
  331.          if ( ! exact) line = I0String::upperCase(line);
  332.  
  333.          // the current line number. for loop.
  334.          line_no = current_line_no;
  335.  
  336.          //  search for text.
  337.          while ( ! line.includes( looked_for ) )
  338.          {
  339.  
  340.             // after first look at whole line.
  341.             offset = 0;
  342.             if (line_no == limit) return;
  343.  
  344.  
  345.             // increment line number.
  346.             line_no += direction_sign;
  347.  
  348.             // get new line.
  349.             line = mle.text(line_no);
  350.  
  351.             // if not exact case, work with upcased string.
  352.             if ( ! exact ) line = I0String::upperCase(line);
  353.  
  354.          };
  355.  
  356. };
  357.  
  358. // optional call back to user after running thread. after searching for text.
  359. void  ListWindowThread::finish()
  360. {
  361.      mle.enableUpdate();         // unfreeze updates.
  362.  
  363.      if (  line.includes( looked_for ) )
  364.      {
  365.  
  366.          // go to begining of found line
  367.          mle.setCursorLinePosition( line_no );
  368.  
  369.          // first position of the found string.
  370.          IPair::Coord first = mle.cursorPosition() + offset +
  371.               (line.*dir_search)(looked_for , start_pos );
  372.  
  373.          // end of the found string.
  374.          IPair::Coord last = first +  search_string.length() - 1;
  375.  
  376.  
  377.  
  378.          // postion past the found string in the direction of travel.
  379.          mle.setCursorPosition ( first + direction_mult *
  380.                                   ( search_string.length() - 1 ) );
  381.  
  382.          // select the found string.
  383.          // cursor will be positined at second parameter of the IRange.
  384.          if ( forward )
  385.             mle.selectRange( IRange(first,last) );
  386.          else
  387.             mle.selectRange( IRange(last,first) );
  388.      };
  389.  
  390.  
  391.  
  392.      info.setText(saved_text);
  393.      OurWindow().enable();
  394.      mle.setFocus();
  395.      return;
  396.  
  397.  
  398. };
  399.  
  400. // Do an importFromFile after determining
  401. // type of the file.
  402. unsigned long ListFrame::import( const char * file)
  403. {
  404.    char buf[2048], cr ;
  405.    {
  406.     ifstream   in( file, ios::binary );
  407.     if (in)
  408.     {
  409.       in.get(buf,sizeof(buf));
  410.  
  411.       int count=in.gcount();
  412.       if ( count == 0 ) cr=0;
  413.       else cr = buf[ count - 1 ];
  414.  
  415.     };
  416.    };
  417.  
  418.    IMultiLineEdit::EOLFormat format =
  419.       ( cr == '\r' ) ?  IMultiLineEdit::cfText
  420.                      :  IMultiLineEdit::noTran;
  421.  
  422.    // import the data.
  423.    return mle.importFromFile( file , format );
  424. };
  425.  
  426. // command handler for main window.
  427. // this code overrides ICommandHandler, gets called
  428. // when command event caused by user from menu, accelerator.
  429. Boolean ListFrame::command( ICommandEvent& event )
  430. {
  431.  
  432.  
  433.    // classify the request.
  434.    switch (  event.commandId() )
  435.    {
  436.     // change font request
  437.     // user wants to change font.
  438.     case IDM_FONT:
  439.        {
  440.           // get current font
  441.           IFont font = mle.font();
  442.           // and store in the settings
  443.           IFontDialog::Settings fsettings( &font );
  444.           // set the title.
  445.           fsettings.setTitle(STR_FONTTITLE);
  446.           // create dialog to get the new font.
  447.           IFontDialog dlg(IWindow::desktopWindow(),this,
  448.                       IFontDialog::defaultStyle() |
  449.                       IFontDialog::resetButton,
  450.                       fsettings);
  451.           // when the constructor returns, dialog has run
  452.  
  453.           if(dlg.pressedOK() )                 // if user said ok.
  454.           {
  455.              mle.setFont(font);                // store new font
  456.  
  457.              // ask user if he want to store this new font as the new default.
  458.              // create message box.
  459.              IMessageBox msg(this);
  460.              if (
  461.                   msg.show(STR_DEFAULTFONT,
  462.                             IMessageBox::queryIcon |
  463.                             IMessageBox::yesNoButton ) ==
  464.                     IMessageBox::yes
  465.                 )
  466.               {
  467.                 // store the new font.
  468.                 ExternalFont(font_source) << font;
  469.               };
  470.           };
  471.           return true;                         // we have handled.
  472.        };
  473.  
  474.     // word wrap on request.
  475.     case IDM_ON:
  476.        {
  477.           // set word wrap if not already.
  478.           if( ! mle.isWordWrap() ) mle.enableWordWrap();
  479.  
  480.           // record word wrapping;
  481.           ExternalWrap(wrap_source) << true;
  482.           return true;     // we have handled.
  483.        };
  484.  
  485.     // word wrap off request.
  486.     case IDM_OFF:
  487.        {
  488.           // if on turn it off
  489.           if( mle.isWordWrap() ) mle.disableWordWrap();
  490.  
  491.           // record no word wrapping;
  492.           ExternalWrap(wrap_source) << false;
  493.           return true;
  494.        };
  495.  
  496.     // open new file on new window request.
  497.     // user wants to open a new file.
  498.     case IDM_OPENNEW :
  499.        {
  500.           char fullfile[_MAX_PATH];            // space for full path name.
  501.  
  502.           // get full path of our current file
  503.           _fullpath(fullfile,file(),sizeof(fullfile));
  504.  
  505.           // fields to break path into
  506.           char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
  507.  
  508.           // break fullpath into fields
  509.           _splitpath(fullfile,drive,dir,fname,ext);
  510.  
  511.           char usepath[_MAX_PATH];             // space for path to use.
  512.  
  513.           // create path to use, with wild card filename.
  514.           _makepath(usepath,drive,dir,"*","");
  515.  
  516.           // declare settings.
  517.           IFileDialog::Settings fsettings;
  518.  
  519.           // set the indicated file name to search for
  520.           fsettings.setFileName( usepath );
  521.  
  522.           // set the ititial drive as has been discovered.
  523.           fsettings.setInitialDrive(drive);
  524.  
  525.           // set title of the  get file name dialog.
  526.           fsettings.setTitle(STR_TITLENEW);
  527.  
  528.           // dialog is to get an existing file.
  529.           fsettings.setOpenDialog();
  530.  
  531.           // declare the dialog on the current frame, with the settings.
  532.           IFileDialog dlg( IWindow::desktopWindow(), this,
  533.                 IFileDialog::defaultStyle(),
  534.                 fsettings);
  535.           // The above call will return when the above modal dialog
  536.           // has already run.
  537.  
  538.           // set the focus back to our edit ring.
  539.           mle.setFocus();
  540.  
  541.           // if the dialog ran successfully.
  542.           if ( dlg.pressedOK() )
  543.           {
  544.              // for each file selected by the dialog.
  545.              for(int i=0; i< dlg.selectedFileCount() ; i++)
  546.              {
  547.                // start a whole new thread to handle the new frame.
  548.                // the new ListThreadFn will be stored in a managed pointer
  549.                // and will be destroyed when the thread exits!
  550.                IThread list ( new ListThreadFn ( dlg.fileName(i) ) );
  551.              };
  552.           };
  553.           return true;                         // Have handled.
  554.           break;
  555.        };
  556.  
  557.     // user wants to Open new file in the current window.
  558.     case IDM_REPLACEFILE:
  559.        {
  560.           // space for the fullfile name in the dialog.
  561.           char fullfile[_MAX_PATH];
  562.  
  563.           // create the fullpath of the current file.
  564.           _fullpath(fullfile, file(),sizeof(fullfile));
  565.  
  566.           // space to store the parts of the current file.
  567.           char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
  568.  
  569.           // split the file into parts.
  570.           _splitpath(fullfile,drive,dir,fname,ext);
  571.  
  572.           // space to store desired file
  573.           char usepath[_MAX_PATH];
  574.  
  575.           // make a wild card file path.
  576.           _makepath(usepath,drive,dir,"*","");
  577.  
  578.           // settings for the dialog.
  579.           IFileDialog::Settings fsettings;
  580.  
  581.           // set files to chose from. all
  582.           fsettings.setFileName( usepath );
  583.  
  584.           // set the initial drive discovered.
  585.           fsettings.setInitialDrive(drive);
  586.  
  587.           // set the title of this dialog.
  588.           fsettings.setTitle(STR_TITLEREPLACE);
  589.  
  590.           // This is an open dialog, choose amoung existing files.
  591.           fsettings.setOpenDialog();
  592.  
  593.  
  594.           // returned OK, is it directroy name of file which is chosen.
  595.           Boolean is_dir , ok ;
  596.           IString chosen_file;
  597.  
  598.           do
  599.           {
  600.              // create the dialog.
  601.              IFileDialog dlg( IWindow::desktopWindow(), this,
  602.                 IFileDialog::defaultStyle() ,
  603.                 fsettings);
  604.              // constructor will return when dialog has run to completion.
  605.  
  606.              ok =  dlg.pressedOK();
  607.  
  608.              if ( ok ) chosen_file = dlg.fileName();
  609.  
  610.              is_dir =  dlg.pressedOK() && IsDir( dlg.fileName() ) ;
  611.  
  612.              if (is_dir) fsettings.setFileName( ( chosen_file + "\\*" ) );
  613.  
  614.           } while ( is_dir );
  615.  
  616.           // if the dialog ran ok.
  617.           if ( ok )
  618.           {
  619.  
  620.              if ( access(chosen_file,04) )             // is it accessable?
  621.              {
  622.                 // if file is not accesable, complain bitterly and leave.
  623.                 IMessageBox ( this )
  624.                 .show(ERR_NOTREAD,IMessageBox::information);
  625.              }
  626.              else
  627.              {
  628.                 mle.hide();                            // hide the client while
  629.                 mle.removeAll();                       // we remove all the
  630.                                                        // lines.
  631.                 // import all lines from
  632.                 import( chosen_file );                 // the selected file.
  633.  
  634.                 file_displayed = chosen_file;          // save current filename.
  635.                 mle.setCursorPosition ( 0 );           // set position=0,0
  636.  
  637.                 info.setText( chosen_file );           // set the filename
  638.                 info.setInactiveText( chosen_file );   // in the info area.
  639.                 setTaskList( chosen_file );
  640.                 mle.show();                            // show edit area again.
  641.              };
  642.           };
  643.  
  644.           // set the focus new edit area
  645.           mle.setFocus();
  646.           return true;                                 // yes, handled.
  647.           break;
  648.        };
  649.  
  650.     // copy to clipboard request.     CTRL+ins
  651.     case IDM_COPYTOCLIPBOARD :
  652.        {
  653.  
  654.  
  655.           // if no text selected, done
  656.           if ( ! mle.hasSelectedText() ) return true;
  657.  
  658.           // get the clipboard window.
  659.           IClipboard clipboard(event.window()->handle());
  660.  
  661.           // empty the clipboard.
  662.           clipboard.empty();
  663.  
  664.           // move in the selected event
  665.           clipboard.setText(mle.selectedText());
  666.           return true;  // we have handled.
  667.           break;
  668.        };
  669.  
  670.     // Handle  all items that display help but are not handled by help system.
  671.     case IDM_COPYRIGHT :
  672.     case IDM_GNUPUBLICLICENCE :
  673.     case IDM_PROGRAMAUTHOR :
  674.        // We require that the item number for these items must be ==
  675.        // the panel ID # this requirement is met in resource editor
  676.        // and ipf editor. We check that it has been met hare.
  677.        {                                               // show help page.
  678.           #if !( (  IDM_COPYRIGHT == Copyright ) && \
  679.                  (  IDM_GNUPUBLICLICENCE == GNU ) && \
  680.                  ( IDM_PROGRAMAUTHOR == Author)      )
  681.           #error Resource ID must be equal to panel ID for app help items.
  682.           #endif
  683.  
  684.           // display the help.
  685.           help.show(IResourceId( event.commandId() ));
  686.           return true;                                 // handled
  687.           break;
  688.        };
  689.  
  690.     // user wants search for text in the mle
  691.     case IDM_SEARCH :
  692.  
  693.        //     get search parameters from user.
  694.  
  695.        // run the search dialog.
  696.        search_dialog.GetToBeSearched();
  697.  
  698.        // deliberate FALLTHRU !!!!!!!
  699.  
  700.     // user wants to search for text string again.
  701.     case IDM_AGAIN :                                   // search for text again.
  702.        {
  703.           // get text to search for
  704.           IString search_string = search_dialog;
  705.  
  706.           // get exact case match parameter.
  707.           Boolean exact = search_dialog.Exact();
  708.  
  709.           // get direction of search.
  710.           Boolean forward = search_dialog.DirectionForward();
  711.  
  712.           // search for the text.
  713.  
  714.           win_thread.init_and_start(search_string, exact, forward);
  715.  
  716.           break;
  717.        };
  718.  
  719.     // the unspecified case.
  720.     default:
  721.        {
  722.           // default do the default handler and return.
  723.           return ICommandHandler::command(event);
  724.        };
  725.    };
  726.    return false;                               // assume we have handled.
  727. };   //  Boolean ListFrame::command( ICommandEvent& event )
  728.  
  729. //
  730. // this handler called when the word wrap menu opened.
  731. // overrides from IMenuHandler. called when Word wrap submenu
  732. // is opened.
  733. Boolean ListFrame::menuShowing ( IMenuEvent& event,ISubmenu& submenu)
  734. {
  735.    // if word wrap menu called.
  736.    if (submenu.id() == IDM_WORDWRAP )
  737.    {
  738.       // is word wrap on?
  739.       Boolean wrap_on = mle.isWordWrap();
  740.  
  741.       // word wrap is of is opposite.
  742.       Boolean wrap_off = !wrap_on;
  743.  
  744.       // set items checked approapiately
  745.       submenu.checkItem(IDM_ON,wrap_on);
  746.       submenu.checkItem(IDM_OFF,wrap_off);
  747.    };
  748.    // pass on to default handler.
  749.    return IMenuHandler::menuShowing( event, submenu);
  750. };
  751.  
  752. // overrides IResizeHandler is called when main frame is resized.
  753. // bug bug bug
  754. // we should only save new size on SHIFT drag, but How do we
  755. // distinguish this case??
  756. // If you know the answer email pelliott@io.com
  757.  
  758. Boolean ListFrame::windowResize(IResizeEvent& evt)
  759. {
  760.    SizeStore(resizer) << evt.newSize();   // Save new size.
  761.    return false;                          // we did not handle, only hooked.
  762. };
  763.  
  764. // overides IHelpHander.
  765. // get s called to find out context help for this window.
  766. // tells keys help what panel to use.
  767. Boolean ListFrame::keysHelpId(IEvent& evt)
  768. {
  769.    int panel = KeysHelp;                  // panel for Keys Help.
  770.    evt.setResult( panel );                // set the panel to use.
  771.    return true;                           // we have handled.
  772. };
  773.  
  774.