home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / listpm7.zip / list.cpp < prev    next >
C/C++ Source or Header  |  1999-07-19  |  36KB  |  968 lines

  1. /*
  2.     listPM list files under Presentation Manager. Uses Open Class Libarary.
  3.     Copyright (C) 1998, 1999  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.     PMB # 181
  21.     11900 Metric Blvd Ste. J
  22.     Austin Tx 78758-3117
  23.     pelliott@io.com
  24.  
  25.     HISTORY
  26.     6-13-1999                  MLEFormat used instead of determining UNIX or DOS eol format.
  27.  
  28. */
  29. #include "listpm.h"            // constants for resourse libarary.
  30.                                // do not edit listpm.h, but use URE to modify.
  31.  
  32. #include "list.hpp"            // List window defined.
  33.  
  34. #include "glbsize.hpp"         // How to store ISize externally.
  35. #include "glbfont.hpp"         // How to store IFont Externally.
  36. #include "glbwrap.hpp"         // How to save word wrap options.
  37. #include "glbcolor.hpp"        // How to save colors
  38. #include "listthrd.hpp"        // List threads defined
  39.  
  40.  
  41. #include "OneOf.hpp"           // define one of a kind of object at runtime.
  42. #include "IsDir.hpp"           // is file a directory?
  43.  
  44.  
  45. #include <iapp.hpp>
  46.  
  47. #include "switch.hpp"
  48.  
  49. #include "pallet.hpp"
  50.  
  51.  
  52. // Global statics interfacing external storage.
  53. // we want One of these objects, but they must be initializied
  54. // after application argc argv are set.
  55. static OneOf<SizeStore> resizer;                 // source of ISize
  56. static OneOf<ExternalFont> font_source;          // source of IFont s
  57. static OneOf<ExternalWrap> wrap_source;          // source of wrap booleans.
  58. static OneOf<ColorStore> color_source;           // source of colors
  59.  
  60.  
  61.           // table of color setting functions must keep in sync with listpm.h
  62.           // COLOR_IDM_START to IDM_COLOR_LAST table of pointers to ListFrame members
  63.           // used to set reset colors.
  64.           // COLOR_STR_START strings must also be in sync
  65.           const ListFrame::listSetColor ListFrame::list_set_colors[] = {
  66.  
  67.                    &ListFrame::ListFrame::setFrameColor<&IWindow::setActiveColor>,
  68.                    &ListFrame::ListFrame::setFrameColor<&IWindow::setBackgroundColor>,
  69.                    &ListFrame::ListFrame::setFrameColor<&IWindow::setForegroundColor>,
  70.                    &ListFrame::ListFrame::setFrameColor<&IWindow::setDisabledBackgroundColor>,
  71.                    &ListFrame::ListFrame::setFrameColor<&IWindow::setDisabledForegroundColor>,
  72.                    &ListFrame::ListFrame::setFrameColor<&IWindow::setHiliteForegroundColor>,
  73.                    &ListFrame::ListFrame::setFrameColor<&IWindow::setHiliteBackgroundColor>,
  74.                    &ListFrame::ListFrame::setFrameColor<&IWindow::setInactiveColor>,
  75.                    &ListFrame::ListFrame::setFrameColor<&IWindow::setShadowColor>,
  76.  
  77.  
  78.                    &ListFrame::ListFrame::setMleColor<&IWindow::setBackgroundColor>,
  79.                    &ListFrame::ListFrame::setMleColor<&IWindow::setForegroundColor>,
  80.  
  81.                    &ListFrame::ListFrame::setColor<&ITitle::setActiveTextBackgroundColor>,
  82.                    &ListFrame::ListFrame::setColor<&ITitle::setActiveTextForegroundColor>,
  83.                    &ListFrame::ListFrame::setColor<&ITitle::setInactiveTextBackgroundColor>,
  84.                    &ListFrame::ListFrame::setColor<&ITitle::setInactiveTextForegroundColor>,
  85.  
  86.                    &ListFrame::ListFrame::setTitlebColor<&IWindow::setActiveColor>,
  87.                    &ListFrame::ListFrame::setTitlebColor<&IWindow::setBackgroundColor>,
  88.                    &ListFrame::ListFrame::setTitlebColor<&IWindow::setForegroundColor>,
  89.                    &ListFrame::ListFrame::setTitlebColor<&IWindow::setDisabledBackgroundColor>,
  90.                    &ListFrame::ListFrame::setTitlebColor<&IWindow::setDisabledForegroundColor>,
  91.                    &ListFrame::ListFrame::setTitlebColor<&IWindow::setHiliteForegroundColor>,
  92.                    &ListFrame::ListFrame::setTitlebColor<&IWindow::setHiliteBackgroundColor>,
  93.                    &ListFrame::ListFrame::setTitlebColor<&IWindow::setInactiveColor>,
  94.                    &ListFrame::ListFrame::setTitlebColor<&IWindow::setShadowColor>
  95.  
  96.              };
  97.           const ListFrame::listResetColor ListFrame::list_reset_colors[] = {
  98.  
  99.                    &ListFrame::ListFrame::resetFrameColor<&IWindow::resetActiveColor>,
  100.                    &ListFrame::ListFrame::resetFrameColor<&IFrameWindow::resetBackgroundColor>,
  101.                    &ListFrame::ListFrame::resetFrameColor<&IWindow::resetForegroundColor>,
  102.                    &ListFrame::ListFrame::resetFrameColor<&IFrameWindow::resetDisabledBackgroundColor>,
  103.                    &ListFrame::ListFrame::resetFrameColor<&IWindow::resetDisabledForegroundColor>,
  104.                    &ListFrame::ListFrame::resetFrameColor<&IWindow::resetHiliteForegroundColor>,
  105.                    &ListFrame::ListFrame::resetFrameColor<&IWindow::resetHiliteBackgroundColor>,
  106.                    &ListFrame::ListFrame::resetFrameColor<&IWindow::resetInactiveColor>,
  107.                    &ListFrame::ListFrame::resetFrameColor<&IWindow::resetShadowColor>,
  108.  
  109.  
  110.                    &ListFrame::ListFrame::resetMleColor<&IWindow::resetBackgroundColor>,
  111.                    &ListFrame::ListFrame::resetMleColor<&IWindow::resetForegroundColor>,
  112.  
  113.                    &ListFrame::ListFrame::resetColor<&ITitle::resetActiveTextBackgroundColor>,
  114.                    &ListFrame::ListFrame::resetColor<&ITitle::resetActiveTextForegroundColor>,
  115.                    &ListFrame::ListFrame::resetColor<&ITitle::resetInactiveTextBackgroundColor>,
  116.                    &ListFrame::ListFrame::resetColor<&ITitle::resetInactiveTextForegroundColor>,
  117.  
  118.  
  119.                    &ListFrame::ListFrame::resetTitlebColor<&IWindow::resetActiveColor>,
  120.                    &ListFrame::ListFrame::resetTitlebColor<&IWindow::resetBackgroundColor>,
  121.                    &ListFrame::ListFrame::resetTitlebColor<&IWindow::resetForegroundColor>,
  122.                    &ListFrame::ListFrame::resetTitlebColor<&IWindow::resetDisabledBackgroundColor>,
  123.                    &ListFrame::ListFrame::resetTitlebColor<&IWindow::resetDisabledForegroundColor>,
  124.                    &ListFrame::ListFrame::resetTitlebColor<&IWindow::resetHiliteForegroundColor>,
  125.                    &ListFrame::ListFrame::resetTitlebColor<&IWindow::resetHiliteBackgroundColor>,
  126.                    &ListFrame::ListFrame::resetTitlebColor<&IWindow::resetInactiveColor>,
  127.                    &ListFrame::ListFrame::resetTitlebColor<&IWindow::resetShadowColor>
  128.  
  129.              };
  130. // number of table setting functions
  131. static const int color_count = ( IDM_COLOR_LAST  - COLOR_IDM_START  + 1);
  132.  
  133.  
  134. // main window consturctor.
  135. // mostly constructed via ctor.
  136. ListFrame::ListFrame( const IString file) :
  137.                   file_displayed(file),                        //save title
  138.                   // frame window from resource id & style
  139.                   IFrameWindow( WIN_UICLLISTER ,
  140.  
  141.                       IFrameWindow::defaultStyle() |          // default style
  142.                       IFrameWindow::shellPosition  |          // wps positions
  143.                       IFrameWindow::accelerator    |          // accelerator
  144.                       IFrameWindow::border         |          // and border
  145.                       IFrameWindow::menuBar        |          // and menu
  146.                       IFrameWindow::minimizedIcon  |          // icon for
  147.                                                               // minimization
  148.                       IFrameWindow::sizingBorder   |          // border sizing
  149.                       IFrameWindow::systemMenu     |          // system menu
  150.                       IFrameWindow::titleBar       ),         // with title bar
  151.  
  152.  
  153.                   // Do not need to access the accelerator, the accelerator attribute insures that there is one (hidden)
  154.                   //acc ( WIN_UICLLISTER , this),             // accelerator
  155.                   info(this),                                 // info area
  156.  
  157.                   // multiline edit field
  158.                   mle ( MLE_TEXT ,this , this, IRectangle(),
  159.                     (IMultiLineEdit::defaultStyle()           // default style
  160.                     | IMultiLineEdit::readOnly                // readonly
  161.                     | IMultiLineEdit::verticalScroll          // scroll vert
  162.                     | IMultiLineEdit::horizontalScroll ) ),   // edit client
  163.                   title( this, STR_TITLE ),                   // title bar
  164.                   help(ID_HELPTABLE,this),                    // attach help win
  165.                   search_dialog( *this , help ),              // search dialog.
  166.                   win_thread(*this,IDM_SEARCHNOT,mle,info)    // window
  167.                                                               // threader.
  168.  
  169. {   // code for constructor
  170.     ICommandHandler::handleEventsFor(this);       // attach command handler.
  171.     IMenuHandler::handleEventsFor(this);          // attach menu handler.
  172.     IResizeHandler::handleEventsFor(this);        // attach resize handler.
  173.     IFocusHandler::handleEventsFor(this);         // focus handler.
  174.  
  175.     SizeStore& l_resizer = resizer;               // get stoed window size
  176.     if (l_resizer.sizeExternal() )                // if an ISize is external
  177.     {
  178.         // get external size
  179.         ISize external_size( l_resizer );
  180.  
  181.         ISize current_size = external_size;
  182.  
  183.         // set window to that size
  184.         sizeTo(current_size);
  185.  
  186.         // code to insure that the window is positioned on the desk
  187.         // top if possible.
  188.  
  189.         // get size of desktop.
  190.         ISize desk_size = IWindow::desktopWindow()->size();
  191.  
  192.         // get position currently proposed.
  193.         IPoint current_position = position();
  194.  
  195.         // assume current position good.
  196.         IPoint new_position = current_position;
  197.  
  198.         if (                            // if positioning is possible!
  199.            // right of window is off screen
  200.            ( current_position.x() + current_size.width() >
  201.                desk_size.width() ) &&
  202.  
  203.            // the whole window will fit on the screen
  204.            ( current_size.width() <= desk_size.width() )
  205.            )
  206.          {
  207.             // degree of freedom in positioning.
  208.             int x_slop = desk_size.width() - current_size.width();
  209.  
  210.             // a plausible pull back from against the right wall.
  211.             int x_pullback = desk_size.width() / 10;
  212.             if ( x_pullback > x_slop) x_pullback = x_slop;
  213.  
  214.             // reanomize the pullback.
  215.             x_pullback *= float(rand()) / float(RAND_MAX) ;
  216.  
  217.             // new position is against right wall pulled back by random amount.
  218.             new_position.setX( x_slop - x_pullback );
  219.          };
  220.  
  221.         // this code is same as above except for doing y co-ordinate.
  222.         if (
  223.            // bottom of window is off screen
  224.            ( current_position.y() + current_size.height() >
  225.               desk_size.height() ) &&
  226.  
  227.            // the whole window will fit on the screen
  228.            ( current_size.height() <= desk_size.height() )
  229.            )
  230.         {
  231.             int y_slop = desk_size.height() - current_size.height();
  232.             int y_pullback = desk_size.height() / 10;
  233.             if ( y_pullback > y_slop) y_pullback = y_slop;
  234.             y_pullback *= float(rand()) / float(RAND_MAX) ;
  235.             new_position.setY( y_slop - y_pullback );
  236.         };
  237.  
  238.         // if we have decided to move the window, move it.
  239.         if ( new_position != current_position) moveTo( new_position );
  240.     };
  241.  
  242.     // if font is stored.
  243.     ExternalFont& l_font_source = font_source;
  244.     if ( l_font_source.FontExistsExternally() )
  245.     {
  246.         // then set the stored font.
  247.         mle.setFont( l_font_source );
  248.     };
  249.  
  250.     Boolean word_wrap = false;                  // assume no word wrap
  251.  
  252.     // if WW option stored.
  253.     ExternalWrap& l_wrap_source = wrap_source;
  254.     if ( l_wrap_source.wrapExternal() )
  255.     {
  256.          word_wrap = l_wrap_source;             // get WW option.
  257.     };
  258.     mle.enableWordWrap(word_wrap);              // set WW option into
  259.  
  260.     ColorStore & color_store = color_source;
  261.     // for each title color
  262.     for( int i = 0; i < color_count ;i++)
  263.     {
  264.        // get string associated with this color index
  265.        // listpm.h STR_ must be in sync with the tables!
  266.        IString color_label =  IApplication::current().userResourceLibrary().
  267.                                                loadString( i + COLOR_STR_START );
  268.  
  269.        // set the key of the color store to be the found key.
  270.        color_store.setKey( color_label );
  271.        // if key exists!
  272.        if ( color_store.colorExternal() )
  273.        {
  274.           // get stored collor, for this key.
  275.           IColor color = color_store;
  276.           // get the function color setter for this key
  277.           // menu items IDs must be in sync in listpm.h
  278.           ListFrame::listSetColor requested_color_set = ListFrame::list_set_colors[ i ];
  279.           // set the color to the stored color.
  280.           (this->*requested_color_set) ( color );
  281.        };
  282.     };
  283.  
  284.  
  285.  
  286.     info.setText(file);                           // set info displayed
  287.                                                   // in info area
  288.     info.setInactiveText(file);                   // ditto, inactive
  289.     setClient( &mle );                            // set edit window as client
  290.  
  291.     help.addLibraries("listpm.hlp");              // library to use for help
  292.     help.setTitle(STR_EXENAME);                   // title of help library.
  293.     IHelpHandler::handleEventsFor(this);          // help handler.
  294.  
  295.  
  296.     // if requested file is accessable
  297.     if (file.length() != 0)
  298.     {
  299.       if ( access(file,04) )
  300.       {
  301.         // if file is not accesable, complain bitterly and leave.
  302.         mle.setFocus();
  303.         show();
  304.         IMessageBox ( this )
  305.          .show(ERR_NOTREAD,IMessageBox::information);
  306.       }
  307.       else
  308.       {
  309.         // if accessable, load into client window.
  310.         import( file);
  311.       };
  312.     }
  313.     else
  314.     {
  315.       while( cin.good() )
  316.       {
  317.         IString line = IString::lineFrom( cin );
  318.         mle.addLineAsLast( line );
  319.       };
  320.     };
  321.     setTaskList( file );
  322.  
  323.     mle.setCursorPosition ( 0 );                  // set cursor at 0,0
  324.     mle.setFocus();                               // give edit area focus, and
  325.     postEvent( control, GOTFOCUS );               // make edit error the focus.
  326.     show();                                       // show.
  327.  
  328.  
  329. };
  330.  
  331. bool ListFrame::gotFocus( IControlEvent& ce )
  332. {
  333.    // if the search field already has focus, skip.
  334.    if ( mle.hasFocus() ) return IFocusHandler::gotFocus( ce );
  335.  
  336.    // when we get focus we post GOTFOCUS message.
  337.    postEvent( control, GOTFOCUS );
  338.  
  339.    return IFocusHandler::gotFocus( ce );
  340. };
  341.  
  342. void ListFrame::setTaskList( const IString& myFile )
  343. {
  344.        changeSwitch(
  345.              handle() ,
  346.              ICurrentApplication::current().currentPID() ,
  347.              IApplication::current().userResourceLibrary().loadString( STR_TLPRE ) +
  348.              myFile );
  349. };
  350.  
  351.        // optional call back to user before running thread.
  352.        // to search for text.
  353. void  ListWindowThread::begin()
  354. {
  355.  
  356.          OurWindow().disable();
  357.          mle.disableUpdate();                      // freeze updates on screen
  358.  
  359.          info.setFocus();
  360.  
  361.          saved_text = info.text();
  362.  
  363.          info.setText(
  364.           IApplication::current().userResourceLibrary().loadString(STR_SEARCH)
  365.           + ": " + search_string);
  366.  
  367.  
  368.          if ( exact )                     // depends on exact case.
  369.             looked_for = search_string;
  370.          else
  371.             looked_for = IString::upperCase(search_string);
  372.          // if not exact case then always work with upcased strings.
  373.          // for both target text and examined text.
  374.  
  375.  
  376.          if(forward)
  377.          {
  378.              direction_sign = direction_mult =1;
  379.              dir_search = &I0String::indexOf;       // forward search fn
  380.              start_pos = 0;                        // starting pos for fn.
  381.  
  382.              limit = mle.numberOfLines() - 1 ;     // last line to look at.
  383.          }
  384.          else
  385.          {
  386.              direction_sign = -1;
  387.              direction_mult = 0;
  388.              dir_search = &I0String::lastIndexOf;   // reverse search fn.
  389.              start_pos = UINT_MAX - 1;             // starting pos for fn.
  390.              limit = 0;                            // last line to look at.
  391.          };
  392.  
  393.          // the current line we are on.
  394.          current_line_no = mle.cursorLinePosition();
  395.  
  396.          // save the current position.
  397.          current_pos  = mle.cursorPosition();
  398.  
  399.          // set the cursor to the begining of this line.
  400.          mle.setCursorLinePosition( current_line_no );
  401.  
  402.          // mark beginning of this line.
  403.          current_bol  = mle.cursorPosition();
  404.  
  405.          // put cursor position back where it was.
  406.          mle.setCursorPosition(current_pos);
  407. };
  408.  
  409. // code to run on other thread.  When searching for text.
  410. void  ListWindowThread::thread()
  411. {
  412.  
  413.          // offset of our cursor in this line.
  414.          offset_within_current_line = current_pos - current_bol;
  415.  
  416.          // get text of current line.
  417.          current_line = mle.text(current_line_no);
  418.  
  419.  
  420.          // the fragment of line we are looking at.
  421.  
  422.          if ( forward )
  423.          {
  424.              // offset of the fragment within the current line
  425.              offset = offset_within_current_line;
  426.  
  427.              // get the relevant fragment of current line = the end.
  428.              line =
  429.                current_line.subString( offset_within_current_line );
  430.          }
  431.          else
  432.          {
  433.              // fragment starts at begin
  434.              offset = 0;
  435.  
  436.              // get the relevant fragment of current line = the beginning.
  437.              line =
  438.                current_line.subString( 0 , offset_within_current_line );
  439.          };
  440.  
  441.          // if !exact case work with upcased line.
  442.          if ( ! exact) line = I0String::upperCase(line);
  443.  
  444.          // the current line number. for loop.
  445.          line_no = current_line_no;
  446.  
  447.          //  search for text.
  448.          while ( ! line.includes( looked_for ) )
  449.          {
  450.  
  451.             // after first look at whole line.
  452.             offset = 0;
  453.             if (line_no == limit) return;
  454.  
  455.  
  456.             // increment line number.
  457.             line_no += direction_sign;
  458.  
  459.             // get new line.
  460.             line = mle.text(line_no);
  461.  
  462.             // if not exact case, work with upcased string.
  463.             if ( ! exact ) line = I0String::upperCase(line);
  464.  
  465.          };
  466.  
  467. };
  468.  
  469. // optional call back to user after running thread. after searching for text.
  470. void  ListWindowThread::finish()
  471. {
  472.      mle.enableUpdate();         // unfreeze updates.
  473.  
  474.      if (  line.includes( looked_for ) )
  475.      {
  476.  
  477.          // go to begining of found line
  478.          mle.setCursorLinePosition( line_no );
  479.  
  480.          // first position of the found string.
  481.          IPair::Coord first = mle.cursorPosition() + offset +
  482.               (line.*dir_search)(looked_for , start_pos );
  483.  
  484.          // end of the found string.
  485.          IPair::Coord last = first +  search_string.length() - 1;
  486.  
  487.  
  488.  
  489.          // postion past the found string in the direction of travel.
  490.          mle.setCursorPosition ( first + direction_mult *
  491.                                   ( search_string.length() - 1 ) );
  492.  
  493.          // select the found string.
  494.          // cursor will be positined at second parameter of the IRange.
  495.          if ( forward )
  496.             mle.selectRange( IRange(first,last) );
  497.          else
  498.             mle.selectRange( IRange(last,first) );
  499.      };
  500.  
  501.  
  502.  
  503.      info.setText(saved_text);
  504.      OurWindow().enable();
  505.      mle.setFocus();
  506.      return;
  507.  
  508.  
  509. };
  510.  
  511. // Do an importFromFile after determining
  512. // type of the file.
  513. unsigned long ListFrame::import( const char * file)
  514. {
  515.  
  516.    IMultiLineEdit::EOLFormat format = IMultiLineEdit::MLEFormat;
  517.  
  518.    // import the data.
  519.    return mle.importFromFile( file , format );
  520. };
  521.  
  522. // command handler for main window.
  523. // this code overrides ICommandHandler, gets called
  524. // when command event caused by user from menu, accelerator.
  525. Boolean ListFrame::command( ICommandEvent& event )
  526. {
  527.  
  528.  
  529.    // classify the request.
  530.    switch (  event.commandId() )
  531.    {
  532.     // have gotten focus
  533.     case GOTFOCUS:
  534.        if ( ! mle.hasFocus() )
  535.        {
  536.           mle.setFocus();
  537.        };
  538.        return false;            // not handled.
  539.        break;
  540.  
  541.     // change font request
  542.     // user wants to change font.
  543.     case IDM_FONT:
  544.        {
  545.           // get current font
  546.           IFont font = mle.font();
  547.           // and store in the settings
  548.           IFontDialog::Settings fsettings( &font );
  549.           // set the title.
  550.           fsettings.setTitle(STR_FONTTITLE);
  551.           // create dialog to get the new font.
  552.           IFontDialog dlg(IWindow::desktopWindow(),this,
  553.                       IFontDialog::defaultStyle() |
  554.                       IFontDialog::resetButton,
  555.                       fsettings);
  556.           // when the constructor returns, dialog has run
  557.  
  558.           if(dlg.pressedOK() )                 // if user said ok.
  559.           {
  560.              mle.setFont(font);                // store new font
  561.  
  562.              // ask user if he want to store this new font as the new default.
  563.              // create message box.
  564.              IMessageBox msg(this);
  565.              if (
  566.                   msg.show(STR_DEFAULTFONT,
  567.                             IMessageBox::queryIcon |
  568.                             IMessageBox::yesNoButton ) ==
  569.                     IMessageBox::yes
  570.                 )
  571.               {
  572.                 // store the new font.
  573.                 ExternalFont(font_source) << font;
  574.               };
  575.           };
  576.           return true;                         // we have handled.
  577.        };
  578.  
  579.     // word wrap on request.
  580.     case IDM_ON:
  581.        {
  582.           // set word wrap if not already.
  583.           if( ! mle.isWordWrap() ) mle.enableWordWrap();
  584.  
  585.           // record word wrapping;
  586.           ExternalWrap(wrap_source) << true;
  587.           return true;     // we have handled.
  588.        };
  589.  
  590.     // word wrap off request.
  591.     case IDM_OFF:
  592.        {
  593.           // if on turn it off
  594.           if( mle.isWordWrap() ) mle.disableWordWrap();
  595.  
  596.           // record no word wrapping;
  597.           ExternalWrap(wrap_source) << false;
  598.           return true;
  599.        };
  600.  
  601.     // open new file on new window request.
  602.     // user wants to open a new file.
  603.     case IDM_OPENNEW :
  604.        {
  605.           char fullfile[_MAX_PATH];            // space for full path name.
  606.  
  607.           // get full path of our current file
  608.           _fullpath(fullfile,file(),sizeof(fullfile));
  609.  
  610.           // fields to break path into
  611.           char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
  612.  
  613.           // break fullpath into fields
  614.           _splitpath(fullfile,drive,dir,fname,ext);
  615.  
  616.           char usepath[_MAX_PATH];             // space for path to use.
  617.  
  618.           // create path to use, with wild card filename.
  619.           _makepath(usepath,drive,dir,"*","");
  620.  
  621.           // declare settings.
  622.           IFileDialog::Settings fsettings;
  623.  
  624.           // set the indicated file name to search for
  625.           fsettings.setFileName( usepath );
  626.  
  627.           // set the ititial drive as has been discovered.
  628.           fsettings.setInitialDrive(drive);
  629.  
  630.           // set title of the  get file name dialog.
  631.           fsettings.setTitle(STR_TITLENEW);
  632.  
  633.           // dialog is to get an existing file.
  634.           fsettings.setOpenDialog();
  635.  
  636.           // declare the dialog on the current frame, with the settings.
  637.           IFileDialog dlg( IWindow::desktopWindow(), this,
  638.                 IFileDialog::defaultStyle(),
  639.                 fsettings);
  640.           // The above call will return when the above modal dialog
  641.           // has already run.
  642.  
  643.           // set the focus back to our edit ring.
  644.           mle.setFocus();
  645.  
  646.           // if the dialog ran successfully.
  647.           if ( dlg.pressedOK() )
  648.           {
  649.              // for each file selected by the dialog.
  650.              for(int i=0; i< dlg.selectedFileCount() ; i++)
  651.              {
  652.                // start a whole new thread to handle the new frame.
  653.                // the new ListThreadFn will be stored in a managed pointer
  654.                // and will be destroyed when the thread exits!
  655.                IThread list ( new ListThreadFn ( dlg.fileName(i) ) );
  656.              };
  657.           };
  658.           return true;                         // Have handled.
  659.           break;
  660.        };
  661.  
  662.     // user wants to Open new file in the current window.
  663.     case IDM_REPLACEFILE:
  664.        {
  665.           // space for the fullfile name in the dialog.
  666.           char fullfile[_MAX_PATH];
  667.  
  668.           // create the fullpath of the current file.
  669.           _fullpath(fullfile, file(),sizeof(fullfile));
  670.  
  671.           // space to store the parts of the current file.
  672.           char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
  673.  
  674.           // split the file into parts.
  675.           _splitpath(fullfile,drive,dir,fname,ext);
  676.  
  677.           // space to store desired file
  678.           char usepath[_MAX_PATH];
  679.  
  680.           // make a wild card file path.
  681.           _makepath(usepath,drive,dir,"*","");
  682.  
  683.           // settings for the dialog.
  684.           IFileDialog::Settings fsettings;
  685.  
  686.           // set files to chose from. all
  687.           fsettings.setFileName( usepath );
  688.  
  689.           // set the initial drive discovered.
  690.           fsettings.setInitialDrive(drive);
  691.  
  692.           // set the title of this dialog.
  693.           fsettings.setTitle(STR_TITLEREPLACE);
  694.  
  695.           // This is an open dialog, choose amoung existing files.
  696.           fsettings.setOpenDialog();
  697.  
  698.  
  699.           // returned OK, is it directroy name of file which is chosen.
  700.           Boolean is_dir , ok ;
  701.           IString chosen_file;
  702.  
  703.           do
  704.           {
  705.              // create the dialog.
  706.              IFileDialog dlg( IWindow::desktopWindow(), this,
  707.                 IFileDialog::defaultStyle() ,
  708.                 fsettings);
  709.              // constructor will return when dialog has run to completion.
  710.  
  711.              ok =  dlg.pressedOK();
  712.  
  713.              if ( ok ) chosen_file = dlg.fileName();
  714.  
  715.              is_dir =  dlg.pressedOK() && IsDir( dlg.fileName() ) ;
  716.  
  717.              if (is_dir) fsettings.setFileName( ( chosen_file + "\\*" ) );
  718.  
  719.           } while ( is_dir );
  720.  
  721.           // if the dialog ran ok.
  722.           if ( ok )
  723.           {
  724.  
  725.              if ( access(chosen_file,04) )             // is it accessable?
  726.              {
  727.                 // if file is not accesable, complain bitterly and leave.
  728.                 IMessageBox ( this )
  729.                 .show(ERR_NOTREAD,IMessageBox::information);
  730.              }
  731.              else
  732.              {
  733.                 mle.hide();                            // hide the client while
  734.                 mle.removeAll();                       // we remove all the
  735.                                                        // lines.
  736.                 // import all lines from
  737.                 import( chosen_file );                 // the selected file.
  738.  
  739.                 file_displayed = chosen_file;          // save current filename.
  740.                 mle.setCursorPosition ( 0 );           // set position=0,0
  741.  
  742.                 info.setText( chosen_file );           // set the filename
  743.                 info.setInactiveText( chosen_file );   // in the info area.
  744.                 setTaskList( chosen_file );
  745.                 mle.show();                            // show edit area again.
  746.              };
  747.           };
  748.  
  749.           // set the focus new edit area
  750.           mle.setFocus();
  751.           return true;                                 // yes, handled.
  752.           break;
  753.        };
  754.  
  755.     // copy to clipboard request.     CTRL+ins
  756.     case IDM_COPYTOCLIPBOARD :
  757.        {
  758.  
  759.  
  760.           // if no text selected, done
  761.           if ( ! mle.hasSelectedText() ) return true;
  762.  
  763.           mle.copy();
  764.           #if 0 // does not work and above mle copy works better.
  765.           // get the clipboard window.
  766.           IClipboard clipboard(event.window()->handle());
  767.  
  768.           // empty the clipboard.
  769.           clipboard.empty();
  770.  
  771.           // move in the selected event
  772.         //clipboard.setText(mle.selectedText());
  773.  
  774.           IString selected ( mle.selectedText() );
  775.  
  776.           int len = selected.length();
  777.  
  778.           char * selectedP = selected;
  779.  
  780.           IString selectedS( selectedP );
  781.           int lenS = selectedS.length();
  782.  
  783.           clipboard.setText( selectedP );
  784.           //clipboard.setData( clipboard.textFormat, selectedP, lenS);
  785.           #endif // does not work and above mle copy works better.
  786.  
  787.           return true;  // we have handled.
  788.           break;
  789.        };
  790.  
  791.     // Handle  all items that display help but are not handled by help system.
  792.     case IDM_COPYRIGHT :
  793.     case IDM_GNUPUBLICLICENCE :
  794.     case IDM_PROGRAMAUTHOR :
  795.        // We require that the item number for these items must be ==
  796.        // the panel ID # this requirement is met in resource editor
  797.        // and ipf editor. We check that it has been met hare.
  798.        {                                               // show help page.
  799.           #if !( (  IDM_COPYRIGHT == Copyright ) && \
  800.                  (  IDM_GNUPUBLICLICENCE == GNU ) && \
  801.                  ( IDM_PROGRAMAUTHOR == Author)      )
  802.           #error Resource ID must be equal to panel ID for app help items.
  803.           #endif
  804.  
  805.           // display the help.
  806.           help.show(IResourceId( event.commandId() ));
  807.           return true;                                 // handled
  808.           break;
  809.        };
  810.  
  811.     // user wants search for text in the mle
  812.     case IDM_SEARCH :
  813.  
  814.        //     get search parameters from user.
  815.  
  816.        // run the search dialog.
  817.        search_dialog.GetToBeSearched();
  818.  
  819.        // deliberate FALLTHRU !!!!!!!
  820.  
  821.     // user wants to search for text string again.
  822.     case IDM_AGAIN :                                   // search for text again.
  823.        {
  824.           // get text to search for
  825.           IString search_string = search_dialog;
  826.  
  827.           // get exact case match parameter.
  828.           Boolean exact = search_dialog.Exact();
  829.  
  830.           // get direction of search.
  831.           Boolean forward = search_dialog.DirectionForward();
  832.  
  833.           // search for the text.
  834.  
  835.           win_thread.init_and_start(search_string, exact, forward);
  836.  
  837.           break;
  838.        };
  839.  
  840.  
  841.    };
  842.  
  843.   // if command ID is in color Range, color ID's must be in sync
  844.   if ( (  event.commandId() >= COLOR_IDM_START ) && (  event.commandId() <= IDM_COLOR_LAST ) )
  845.   {
  846.  
  847.           // get set function, reset function for this menu request.
  848.           // list must be in sync with IDs in listpm.h
  849.           ListFrame::listSetColor requested_color_set = list_set_colors[ event.commandId() - COLOR_IDM_START ];
  850.           ListFrame::listResetColor requested_color_reset = list_reset_colors[ event.commandId() - COLOR_IDM_START ];
  851.  
  852.           // get string ID for this menu request.
  853.           // listpm.h STR_ for these ID's must be in sync.
  854.           IString color_label =  IApplication::current().userResourceLibrary().
  855.                                                loadString(  event.commandId() - COLOR_IDM_START
  856.                                                + COLOR_STR_START );
  857.  
  858.           // run the select color dialog.
  859.           int frameX = 0, frameY = 0;
  860.           IPalletDialog colorDialog(color_label,frameX,frameY, this);
  861.           colorDialog.showModally();
  862.  
  863.           // if reset pushed reset the color
  864.           if (colorDialog.result() == ID_RESET)
  865.           {
  866.              pcolor chosen_color = colorDialog.color();
  867.              IColor ichosen_color = chosen_color;
  868.              (this->*requested_color_reset)();
  869.  
  870.              // ask user if he want to REVERT this  COLOR TO THE NEW default.
  871.              // create message box.
  872.              IMessageBox msg(this);
  873.              if (
  874.                   msg.show(STR_REVERTQUERY,
  875.                             IMessageBox::queryIcon |
  876.                             IMessageBox::yesNoButton ) ==
  877.                     IMessageBox::yes
  878.                 )
  879.              {
  880.                 ColorStore & color_store = color_source;
  881.                 // set key to delete
  882.                 color_store.setKey( color_label );
  883.                 if ( color_store.colorExternal() ) color_store.deleteKey();
  884.                 // deleting the key means that future ListFrame windows
  885.                 // will not set a stored color!
  886.              };
  887.           };
  888.  
  889.           // if OK set the color.
  890.           if (colorDialog.result() == ID_OK)
  891.           {
  892.              // get color chosen.
  893.              pcolor chosen_color = colorDialog.color();
  894.              // convert to an IColor
  895.              IColor ichosen_color = chosen_color;
  896.              // set this new color
  897.              (this->*requested_color_set)(ichosen_color);
  898.  
  899.              // ask user if he want to store this new COLOR as the new default.
  900.              // create message box.
  901.              IMessageBox msg(this);
  902.              if (
  903.                   msg.show(STR_COLORSAVEQUERY,
  904.                             IMessageBox::queryIcon |
  905.                             IMessageBox::yesNoButton ) ==
  906.                     IMessageBox::yes
  907.                 )
  908.              {
  909.                 // get reference to color store.
  910.                 ColorStore & color_store = color_source;
  911.                 // set the KEY ID to store
  912.                 color_store.setKey( color_label );
  913.                 // store the new color.
  914.                 color_store << chosen_color;
  915.              };
  916.           };
  917.           return true;
  918.   };
  919.  
  920.    return ICommandHandler::command(event);
  921. };   //  Boolean ListFrame::command( ICommandEvent& event )
  922.  
  923. //
  924. // this handler called when the word wrap menu opened.
  925. // overrides from IMenuHandler. called when Word wrap submenu
  926. // is opened.
  927. Boolean ListFrame::menuShowing ( IMenuEvent& event,ISubmenu& submenu)
  928. {
  929.    // if word wrap menu called.
  930.    if (submenu.id() == IDM_WORDWRAP )
  931.    {
  932.       // is word wrap on?
  933.       Boolean wrap_on = mle.isWordWrap();
  934.  
  935.       // word wrap is of is opposite.
  936.       Boolean wrap_off = !wrap_on;
  937.  
  938.       // set items checked approapiately
  939.       submenu.checkItem(IDM_ON,wrap_on);
  940.       submenu.checkItem(IDM_OFF,wrap_off);
  941.    };
  942.    // pass on to default handler.
  943.    return IMenuHandler::menuShowing( event, submenu);
  944. };
  945.  
  946. // overrides IResizeHandler is called when main frame is resized.
  947. // bug bug bug
  948. // we should only save new size on SHIFT drag, but How do we
  949. // distinguish this case??
  950. // If you know the answer email pelliott@io.com
  951.  
  952. Boolean ListFrame::windowResize(IResizeEvent& evt)
  953. {
  954.    SizeStore(resizer) << evt.newSize();   // Save new size.
  955.    return false;                          // we did not handle, only hooked.
  956. };
  957.  
  958. // overides IHelpHander.
  959. // get s called to find out context help for this window.
  960. // tells keys help what panel to use.
  961. Boolean ListFrame::keysHelpId(IEvent& evt)
  962. {
  963.    int panel = KeysHelp;                  // panel for Keys Help.
  964.    evt.setResult( panel );                // set the panel to use.
  965.    return true;                           // we have handled.
  966. };
  967.  
  968.