home *** CD-ROM | disk | FTP | other *** search
- /*
- listPM list files under Presentation Manager. Uses Open Class Libarary.
- Copyright (C) 1998 Paul Elliott
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- Paul Elliott
- 11900 Metric Blvd #J-181
- Austin Tx 78758-3117
- pelliott@io.com
- */
- #include "listpm.h" // constants for resourse libarary.
- // do not edit listpm.h, but use URE to modify.
-
- #include "list.hpp" // List window defined.
-
- #include "glbsize.hpp" // How to store ISize externally.
- #include "glbfont.hpp" // How to store IFont Externally.
- #include "glbwrap.hpp" // How to save word wrap options.
- #include "listthrd.hpp" // List threads defined
-
-
- #include "OneOf.hpp" // define one of a kind of object at runtime.
- #include "IsDir.hpp" // is file a directory?
-
-
- #include <iapp.hpp>
-
- // manipulate files.
- #include <iostream.h>
- #include <iomanip.h>
- #include <fstream.h>
- #include "switch.hpp"
-
-
-
-
- // Global statics interfacing external storage.
- // we want One of these objects, but they must be initializied
- // after application argc argv are set.
- static OneOf<SizeStore> resizer; // source of ISize
- static OneOf<ExternalFont> font_source; // source of IFont s
- static OneOf<ExternalWrap> wrap_source; // source of wrap booleans.
-
- // main window consturctor.
- // mostly constructed via ctor.
- ListFrame::ListFrame( const IString file) :
- file_displayed(file), //save title
- // frame window from resource id & style
- IFrameWindow( WIN_UICLLISTER ,
-
- IFrameWindow::defaultStyle() | // default style
- IFrameWindow::shellPosition | // wps positions
- IFrameWindow::accelerator | // accelerator
- IFrameWindow::border | // and border
- IFrameWindow::menuBar | // and menu
- IFrameWindow::minimizedIcon | // icon for
- // minimization
- IFrameWindow::sizingBorder | // border sizing
- IFrameWindow::systemMenu | // system menu
- IFrameWindow::titleBar ), // with title bar
-
-
-
- acc ( WIN_UICLLISTER , this), // accelerator
- info(this), // info area
-
- // multiline edit field
- mle ( MLE_TEXT ,this , this, IRectangle(),
- (IMultiLineEdit::defaultStyle() // default style
- | IMultiLineEdit::readOnly // readonly
- | IMultiLineEdit::verticalScroll // scroll vert
- | IMultiLineEdit::horizontalScroll ) ), // edit client
- title( this, STR_TITLE ), // title bar
- help(ID_HELPTABLE,this), // attach help win
- search_dialog( *this , help ), // search dialog.
- win_thread(*this,IDM_SEARCHNOT,mle,info) // window
- // threader.
-
- { // code for constructor
- ICommandHandler::handleEventsFor(this); // attach command handler.
- IMenuHandler::handleEventsFor(this); // attach menu handler.
- IResizeHandler::handleEventsFor(this); // attach resize handler.
-
- SizeStore& l_resizer = resizer; // get stoed window size
- if (l_resizer.sizeExternal() ) // if an ISize is external
- {
- // get external size
- ISize external_size( l_resizer );
-
- ISize current_size = external_size;
-
- // set window to that size
- sizeTo(current_size);
-
- // code to insure that the window is positioned on the desk
- // top if possible.
-
- // get size of desktop.
- ISize desk_size = IWindow::desktopWindow()->size();
-
- // get position currently proposed.
- IPoint current_position = position();
-
- // assume current position good.
- IPoint new_position = current_position;
-
- if ( // if positioning is possible!
- // right of window is off screen
- ( current_position.x() + current_size.width() >
- desk_size.width() ) &&
-
- // the whole window will fit on the screen
- ( current_size.width() <= desk_size.width() )
- )
- {
- // degree of freedom in positioning.
- int x_slop = desk_size.width() - current_size.width();
-
- // a plausible pull back from against the right wall.
- int x_pullback = desk_size.width() / 10;
- if ( x_pullback > x_slop) x_pullback = x_slop;
-
- // reanomize the pullback.
- x_pullback *= float(rand()) / float(RAND_MAX) ;
-
- // new position is against right wall pulled back by random amount.
- new_position.setX( x_slop - x_pullback );
- };
-
- // this code is same as above except for doing y co-ordinate.
- if (
- // bottom of window is off screen
- ( current_position.y() + current_size.height() >
- desk_size.height() ) &&
-
- // the whole window will fit on the screen
- ( current_size.height() <= desk_size.height() )
- )
- {
- int y_slop = desk_size.height() - current_size.height();
- int y_pullback = desk_size.height() / 10;
- if ( y_pullback > y_slop) y_pullback = y_slop;
- y_pullback *= float(rand()) / float(RAND_MAX) ;
- new_position.setY( y_slop - y_pullback );
- };
-
- // if we have decided to move the window, move it.
- if ( new_position != current_position) moveTo( new_position );
- };
-
- // if font is stored.
- ExternalFont& l_font_source = font_source;
- if ( l_font_source.FontExistsExternally() )
- {
- // then set the stored font.
- mle.setFont( l_font_source );
- };
-
- Boolean word_wrap = false; // assume no word wrap
-
- // if WW option stored.
- ExternalWrap& l_wrap_source = wrap_source;
- if ( l_wrap_source.wrapExternal() )
- {
- word_wrap = l_wrap_source; // get WW option.
- };
- mle.enableWordWrap(word_wrap); // set WW option into
- // edit client.
-
-
- info.setText(file); // set info displayed
- // in info area
- info.setInactiveText(file); // ditto, inactive
- setClient( &mle ); // set edit window as client
-
- help.addLibraries("listpm.hlp"); // library to use for help
- help.setTitle(STR_EXENAME); // title of help library.
- IHelpHandler::handleEventsFor(this); // help handler.
-
-
- // if requested file is accessable
- if (file.length() != 0)
- {
- if ( access(file,04) )
- {
- // if file is not accesable, complain bitterly and leave.
- mle.setFocus();
- show();
- IMessageBox ( this )
- .show(ERR_NOTREAD,IMessageBox::information);
- }
- else
- {
- // if accessable, load into client window.
- import( file);
- };
- }
- else
- {
- while( cin.good() )
- {
- IString line = IString::lineFrom( cin );
- mle.addLineAsLast( line );
- };
- };
- setTaskList( file );
-
- mle.setCursorPosition ( 0 ); // set cursor at 0,0
- mle.setFocus(); // give edit area focus, and
- show(); // show.
-
-
- };
-
- void ListFrame::setTaskList( const IString& myFile )
- {
- changeSwitch(
- handle() ,
- ICurrentApplication::current().currentPID() ,
- IApplication::current().userResourceLibrary().loadString( STR_TLPRE ) +
- myFile );
- };
-
- // optional call back to user before running thread.
- // to search for text.
- void ListWindowThread::begin()
- {
-
- OurWindow().disable();
- mle.disableUpdate(); // freeze updates on screen
-
- info.setFocus();
-
- saved_text = info.text();
-
- info.setText(
- IApplication::current().userResourceLibrary().loadString(STR_SEARCH)
- + ": " + search_string);
-
-
- if ( exact ) // depends on exact case.
- looked_for = search_string;
- else
- looked_for = IString::upperCase(search_string);
- // if not exact case then always work with upcased strings.
- // for both target text and examined text.
-
-
-
-
-
- if(forward)
- {
- direction_sign = direction_mult =1;
- dir_search = I0String::indexOf; // forward search fn
- start_pos = 0; // starting pos for fn.
-
- limit = mle.numberOfLines() - 1 ; // last line to look at.
- }
- else
- {
- direction_sign = -1;
- direction_mult = 0;
- dir_search = I0String::lastIndexOf; // reverse search fn.
- start_pos = UINT_MAX - 1; // starting pos for fn.
- limit = 0; // last line to look at.
- };
-
- // the current line we are on.
- current_line_no = mle.cursorLinePosition();
-
- // save the current position.
- current_pos = mle.cursorPosition();
-
- // set the cursor to the begining of this line.
- mle.setCursorLinePosition( current_line_no );
-
- // mark beginning of this line.
- current_bol = mle.cursorPosition();
-
- // put cursor position back where it was.
- mle.setCursorPosition(current_pos);
- };
-
- // code to run on other thread. When searching for text.
- void ListWindowThread::thread()
- {
-
- // offset of our cursor in this line.
- offset_within_current_line = current_pos - current_bol;
-
- // get text of current line.
- current_line = mle.text(current_line_no);
-
-
- // the fragment of line we are looking at.
-
- if ( forward )
- {
- // offset of the fragment within the current line
- offset = offset_within_current_line;
-
- // get the relevant fragment of current line = the end.
- line =
- current_line.subString( offset_within_current_line );
- }
- else
- {
- // fragment starts at begin
- offset = 0;
-
- // get the relevant fragment of current line = the beginning.
- line =
- current_line.subString( 0 , offset_within_current_line );
- };
-
- // if !exact case work with upcased line.
- if ( ! exact) line = I0String::upperCase(line);
-
- // the current line number. for loop.
- line_no = current_line_no;
-
- // search for text.
- while ( ! line.includes( looked_for ) )
- {
-
- // after first look at whole line.
- offset = 0;
- if (line_no == limit) return;
-
-
- // increment line number.
- line_no += direction_sign;
-
- // get new line.
- line = mle.text(line_no);
-
- // if not exact case, work with upcased string.
- if ( ! exact ) line = I0String::upperCase(line);
-
- };
-
- };
-
- // optional call back to user after running thread. after searching for text.
- void ListWindowThread::finish()
- {
- mle.enableUpdate(); // unfreeze updates.
-
- if ( line.includes( looked_for ) )
- {
-
- // go to begining of found line
- mle.setCursorLinePosition( line_no );
-
- // first position of the found string.
- IPair::Coord first = mle.cursorPosition() + offset +
- (line.*dir_search)(looked_for , start_pos );
-
- // end of the found string.
- IPair::Coord last = first + search_string.length() - 1;
-
-
-
- // postion past the found string in the direction of travel.
- mle.setCursorPosition ( first + direction_mult *
- ( search_string.length() - 1 ) );
-
- // select the found string.
- // cursor will be positined at second parameter of the IRange.
- if ( forward )
- mle.selectRange( IRange(first,last) );
- else
- mle.selectRange( IRange(last,first) );
- };
-
-
-
- info.setText(saved_text);
- OurWindow().enable();
- mle.setFocus();
- return;
-
-
- };
-
- // Do an importFromFile after determining
- // type of the file.
- unsigned long ListFrame::import( const char * file)
- {
- char buf[2048], cr ;
- {
- ifstream in( file, ios::binary );
- if (in)
- {
- in.get(buf,sizeof(buf));
-
- int count=in.gcount();
- if ( count == 0 ) cr=0;
- else cr = buf[ count - 1 ];
-
- };
- };
-
- IMultiLineEdit::EOLFormat format =
- ( cr == '\r' ) ? IMultiLineEdit::cfText
- : IMultiLineEdit::noTran;
-
- // import the data.
- return mle.importFromFile( file , format );
- };
-
- // command handler for main window.
- // this code overrides ICommandHandler, gets called
- // when command event caused by user from menu, accelerator.
- Boolean ListFrame::command( ICommandEvent& event )
- {
-
-
- // classify the request.
- switch ( event.commandId() )
- {
- // change font request
- // user wants to change font.
- case IDM_FONT:
- {
- // get current font
- IFont font = mle.font();
- // and store in the settings
- IFontDialog::Settings fsettings( &font );
- // set the title.
- fsettings.setTitle(STR_FONTTITLE);
- // create dialog to get the new font.
- IFontDialog dlg(IWindow::desktopWindow(),this,
- IFontDialog::defaultStyle() |
- IFontDialog::resetButton,
- fsettings);
- // when the constructor returns, dialog has run
-
- if(dlg.pressedOK() ) // if user said ok.
- {
- mle.setFont(font); // store new font
-
- // ask user if he want to store this new font as the new default.
- // create message box.
- IMessageBox msg(this);
- if (
- msg.show(STR_DEFAULTFONT,
- IMessageBox::queryIcon |
- IMessageBox::yesNoButton ) ==
- IMessageBox::yes
- )
- {
- // store the new font.
- ExternalFont(font_source) << font;
- };
- };
- return true; // we have handled.
- };
-
- // word wrap on request.
- case IDM_ON:
- {
- // set word wrap if not already.
- if( ! mle.isWordWrap() ) mle.enableWordWrap();
-
- // record word wrapping;
- ExternalWrap(wrap_source) << true;
- return true; // we have handled.
- };
-
- // word wrap off request.
- case IDM_OFF:
- {
- // if on turn it off
- if( mle.isWordWrap() ) mle.disableWordWrap();
-
- // record no word wrapping;
- ExternalWrap(wrap_source) << false;
- return true;
- };
-
- // open new file on new window request.
- // user wants to open a new file.
- case IDM_OPENNEW :
- {
- char fullfile[_MAX_PATH]; // space for full path name.
-
- // get full path of our current file
- _fullpath(fullfile,file(),sizeof(fullfile));
-
- // fields to break path into
- char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
-
- // break fullpath into fields
- _splitpath(fullfile,drive,dir,fname,ext);
-
- char usepath[_MAX_PATH]; // space for path to use.
-
- // create path to use, with wild card filename.
- _makepath(usepath,drive,dir,"*","");
-
- // declare settings.
- IFileDialog::Settings fsettings;
-
- // set the indicated file name to search for
- fsettings.setFileName( usepath );
-
- // set the ititial drive as has been discovered.
- fsettings.setInitialDrive(drive);
-
- // set title of the get file name dialog.
- fsettings.setTitle(STR_TITLENEW);
-
- // dialog is to get an existing file.
- fsettings.setOpenDialog();
-
- // declare the dialog on the current frame, with the settings.
- IFileDialog dlg( IWindow::desktopWindow(), this,
- IFileDialog::defaultStyle(),
- fsettings);
- // The above call will return when the above modal dialog
- // has already run.
-
- // set the focus back to our edit ring.
- mle.setFocus();
-
- // if the dialog ran successfully.
- if ( dlg.pressedOK() )
- {
- // for each file selected by the dialog.
- for(int i=0; i< dlg.selectedFileCount() ; i++)
- {
- // start a whole new thread to handle the new frame.
- // the new ListThreadFn will be stored in a managed pointer
- // and will be destroyed when the thread exits!
- IThread list ( new ListThreadFn ( dlg.fileName(i) ) );
- };
- };
- return true; // Have handled.
- break;
- };
-
- // user wants to Open new file in the current window.
- case IDM_REPLACEFILE:
- {
- // space for the fullfile name in the dialog.
- char fullfile[_MAX_PATH];
-
- // create the fullpath of the current file.
- _fullpath(fullfile, file(),sizeof(fullfile));
-
- // space to store the parts of the current file.
- char drive[_MAX_DRIVE],dir[_MAX_DIR],fname[_MAX_FNAME],ext[_MAX_EXT];
-
- // split the file into parts.
- _splitpath(fullfile,drive,dir,fname,ext);
-
- // space to store desired file
- char usepath[_MAX_PATH];
-
- // make a wild card file path.
- _makepath(usepath,drive,dir,"*","");
-
- // settings for the dialog.
- IFileDialog::Settings fsettings;
-
- // set files to chose from. all
- fsettings.setFileName( usepath );
-
- // set the initial drive discovered.
- fsettings.setInitialDrive(drive);
-
- // set the title of this dialog.
- fsettings.setTitle(STR_TITLEREPLACE);
-
- // This is an open dialog, choose amoung existing files.
- fsettings.setOpenDialog();
-
-
- // returned OK, is it directroy name of file which is chosen.
- Boolean is_dir , ok ;
- IString chosen_file;
-
- do
- {
- // create the dialog.
- IFileDialog dlg( IWindow::desktopWindow(), this,
- IFileDialog::defaultStyle() ,
- fsettings);
- // constructor will return when dialog has run to completion.
-
- ok = dlg.pressedOK();
-
- if ( ok ) chosen_file = dlg.fileName();
-
- is_dir = dlg.pressedOK() && IsDir( dlg.fileName() ) ;
-
- if (is_dir) fsettings.setFileName( ( chosen_file + "\\*" ) );
-
- } while ( is_dir );
-
- // if the dialog ran ok.
- if ( ok )
- {
-
- if ( access(chosen_file,04) ) // is it accessable?
- {
- // if file is not accesable, complain bitterly and leave.
- IMessageBox ( this )
- .show(ERR_NOTREAD,IMessageBox::information);
- }
- else
- {
- mle.hide(); // hide the client while
- mle.removeAll(); // we remove all the
- // lines.
- // import all lines from
- import( chosen_file ); // the selected file.
-
- file_displayed = chosen_file; // save current filename.
- mle.setCursorPosition ( 0 ); // set position=0,0
-
- info.setText( chosen_file ); // set the filename
- info.setInactiveText( chosen_file ); // in the info area.
- setTaskList( chosen_file );
- mle.show(); // show edit area again.
- };
- };
-
- // set the focus new edit area
- mle.setFocus();
- return true; // yes, handled.
- break;
- };
-
- // copy to clipboard request. CTRL+ins
- case IDM_COPYTOCLIPBOARD :
- {
-
-
- // if no text selected, done
- if ( ! mle.hasSelectedText() ) return true;
-
- // get the clipboard window.
- IClipboard clipboard(event.window()->handle());
-
- // empty the clipboard.
- clipboard.empty();
-
- // move in the selected event
- clipboard.setText(mle.selectedText());
- return true; // we have handled.
- break;
- };
-
- // Handle all items that display help but are not handled by help system.
- case IDM_COPYRIGHT :
- case IDM_GNUPUBLICLICENCE :
- case IDM_PROGRAMAUTHOR :
- // We require that the item number for these items must be ==
- // the panel ID # this requirement is met in resource editor
- // and ipf editor. We check that it has been met hare.
- { // show help page.
- #if !( ( IDM_COPYRIGHT == Copyright ) && \
- ( IDM_GNUPUBLICLICENCE == GNU ) && \
- ( IDM_PROGRAMAUTHOR == Author) )
- #error Resource ID must be equal to panel ID for app help items.
- #endif
-
- // display the help.
- help.show(IResourceId( event.commandId() ));
- return true; // handled
- break;
- };
-
- // user wants search for text in the mle
- case IDM_SEARCH :
-
- // get search parameters from user.
-
- // run the search dialog.
- search_dialog.GetToBeSearched();
-
- // deliberate FALLTHRU !!!!!!!
-
- // user wants to search for text string again.
- case IDM_AGAIN : // search for text again.
- {
- // get text to search for
- IString search_string = search_dialog;
-
- // get exact case match parameter.
- Boolean exact = search_dialog.Exact();
-
- // get direction of search.
- Boolean forward = search_dialog.DirectionForward();
-
- // search for the text.
-
- win_thread.init_and_start(search_string, exact, forward);
-
- break;
- };
-
- // the unspecified case.
- default:
- {
- // default do the default handler and return.
- return ICommandHandler::command(event);
- };
- };
- return false; // assume we have handled.
- }; // Boolean ListFrame::command( ICommandEvent& event )
-
- //
- // this handler called when the word wrap menu opened.
- // overrides from IMenuHandler. called when Word wrap submenu
- // is opened.
- Boolean ListFrame::menuShowing ( IMenuEvent& event,ISubmenu& submenu)
- {
- // if word wrap menu called.
- if (submenu.id() == IDM_WORDWRAP )
- {
- // is word wrap on?
- Boolean wrap_on = mle.isWordWrap();
-
- // word wrap is of is opposite.
- Boolean wrap_off = !wrap_on;
-
- // set items checked approapiately
- submenu.checkItem(IDM_ON,wrap_on);
- submenu.checkItem(IDM_OFF,wrap_off);
- };
- // pass on to default handler.
- return IMenuHandler::menuShowing( event, submenu);
- };
-
- // overrides IResizeHandler is called when main frame is resized.
- // bug bug bug
- // we should only save new size on SHIFT drag, but How do we
- // distinguish this case??
- // If you know the answer email pelliott@io.com
-
- Boolean ListFrame::windowResize(IResizeEvent& evt)
- {
- SizeStore(resizer) << evt.newSize(); // Save new size.
- return false; // we did not handle, only hooked.
- };
-
- // overides IHelpHander.
- // get s called to find out context help for this window.
- // tells keys help what panel to use.
- Boolean ListFrame::keysHelpId(IEvent& evt)
- {
- int panel = KeysHelp; // panel for Keys Help.
- evt.setResult( panel ); // set the panel to use.
- return true; // we have handled.
- };
-
-