home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / listpm3.zip / source / list.cpp < prev    next >
C/C++ Source or Header  |  1996-09-11  |  26KB  |  749 lines

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