home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / ool.zip / OOL / samples / sample1 / sample1.cpp < prev    next >
C/C++ Source or Header  |  1997-04-07  |  16KB  |  491 lines

  1. #include "sample1.h"
  2.  
  3. #include XColor_i
  4. #include XFileDialog_i
  5. #include XString_i
  6. #include XMessageBox_i
  7. #include XException_i
  8. #include XDragEvent_i
  9. #include XDragHandler_i
  10. #include XDragItem_i
  11. #include XFile_i
  12. #include XFrame_i
  13. #include XToolBar_i
  14. #include XPushButton_i
  15. #include XFileInfo_i
  16. #include XMLESearch_i
  17. #include XCheckBox_i
  18. #include XFontDialog_i
  19.  
  20. #include <stdlib.h>
  21. #include <string.h>
  22. /* This is the code for sample1, a simple text-editor */
  23.  
  24. class MyMLE: public XMultiLineEdit
  25. {
  26.       MyAppWindow * owner;
  27.    public:
  28.       MyMLE( MyAppWindow * w, XRect * r): XMultiLineEdit( w, r, MY_MLE, MLE_HORZSCROLL | MLE_VERTSCROLL | WIN_VISIBLE) { owner = w; }
  29.       void DoControl(XControlEvent*);
  30. };
  31.  
  32. /* we want to accept files wich are dropped on our window, so we need */
  33. /* a handler wich can handle this messages for drag/drop. we need to derive */
  34. /* a class from class XDragHandler and overwrite the method HandleEvent */
  35. /* and the constructor */
  36. class MyDragHandler: public XDragHandler
  37. {
  38.    public:
  39.       MyDragHandler( XWindow * w): XDragHandler( w ) { ;}
  40.       void HandleEvent(XDragEvent*);
  41. };
  42.  
  43.  
  44. /* here the method HandleEvent is overridden, so we can handle drag/drop events*/
  45. void MyDragHandler :: HandleEvent ( XDragEvent * event)
  46. {
  47.    switch( event->GetEventID())
  48.       {
  49.          /* the mousepointer is over the MLE holding one or more objects */
  50.          case DRG_DRAGOVER:
  51.             {
  52.                SHORT i;
  53.                XDragItem item;
  54.                /* ask for every object the type and format */
  55.                for(i=0; i < event->GetDragItemCount(); i ++)
  56.                  {
  57.                     event->GetDragItem( &item, i);
  58.                     if(item.VerifyItemType( DRG_M_FILE ) == FALSE)
  59.                        {
  60.                           /* no textfile, we will not accept these objects */
  61.                           event->SetAcceptMode( DRG_NEVERDROP);
  62.                           return;
  63.                        }
  64.                  }
  65.                event->SetAcceptMode( DRG_DROP);       //ok, can be dropped
  66.                event->SetOperation( DO_COPY);         //we will work with a copy
  67.              }
  68.              return;
  69.          /* one or more object are dropped, because we∩ve tested the format (see above) */
  70.          /* we don∩t have to test it here again, the object will be files */
  71.          case DRG_DROP:
  72.             {
  73.                XDragItem item;
  74.                XString name, container;
  75.                SHORT i;
  76.  
  77.                /* query for every object the information we need */
  78.                for(i=0; i < event->GetDragItemCount(); i++)
  79.                   {
  80.                      event->GetDragItem( &item, i);
  81.                      item.Accept();                        //let the sender know that we accept the object
  82.  
  83.                      item.GetName( &name);               //query the filename
  84.                      item.GetContainerName( &container); //query the directory
  85.                      container+= name;                     //make a complete path
  86.  
  87.                      MyAppWindow * appWin = (MyAppWindow*) GetWindow()->QueryWindow( WIN_PARENT);
  88.                      appWin->LoadFile( container );        //load the file
  89.                   }
  90.             }
  91.             return;
  92.       }
  93. }
  94.  
  95.  
  96. /* here the mainwindow will be created */
  97. MyAppWindow :: MyAppWindow( XResourceLibrary * resLib, XResource * r ): XFrameWindow( r, "Sample1", XFrameWindow::defaultStyle | FRM_ICON )
  98. {
  99.    loading = FALSE;
  100.  
  101.    XRect rec( 100, 100, 500, 350);
  102.    SetSize( &rec );
  103.    /* we create a MLE-control; because the MLE is used as client we dont want a border */
  104.    /* and don∩t use the defaults (see <xmle.h>) */
  105.    XRect rec2( 0, 0, 400, 250);
  106.    mle = new MyMLE( this, &rec2 );
  107.  
  108.    /*set backgroundcolor to white*/
  109.    XColor col( COL_WHITE);
  110.    mle->SetBackgroundColor( &col );
  111.  
  112.    /* the MLE is used as a new client-area, so sizing and moving is automaticaly done */
  113.    SetClient( mle );
  114.  
  115.    /* we want a menubar, it is defined in the resources of the exe-file with the id IDM_MAIN */
  116.    XResource rs( IDM_MAIN, resLib);
  117.    menu = new XMenuBar( this, &rs);
  118.  
  119.    /* we put a string into the MLE */
  120.    mle->SetText( "this is our MLE where you can edit your text...");
  121.  
  122.    /*we generate our drag-handler and attach it to the MLE */
  123.    MyDragHandler * myDragHandler = new MyDragHandler( mle );
  124.  
  125.    /* setup our needed flags */
  126.    saved = TRUE;
  127.    loaded = FALSE;
  128.  
  129.    dlg = NULL;
  130.    /*the mle get the focus */
  131.    mle->SetFocus();
  132. }
  133.  
  134.  
  135. class SearchDialog: public XFrameWindow
  136. {
  137.       XMultiLineEdit * mle;
  138.       MyAppWindow * win;
  139.       XMLESearch search;
  140.    public:
  141.       BOOL DoCommand( LONG );
  142.       void DoControl( XControlEvent*);
  143.       SearchDialog( XMultiLineEdit*, XResource *, MyAppWindow * );
  144.       ~SearchDialog();
  145. };
  146.  
  147.  
  148. SearchDialog :: ~SearchDialog()
  149. {
  150.    win->dlg = NULL;
  151. }
  152.  
  153.  
  154. void SearchDialog :: DoControl( XControlEvent * event )
  155. {
  156.    switch( event->GetEventID() )
  157.      {
  158.         case WIN_CHANGED:
  159.            switch( event->GetWindowID())
  160.               {
  161.                  case CHECK_CASE:
  162.                     {
  163.                        XCheckBox * c = (XCheckBox*) event->GetWindow();
  164.                        if( c->IsSelected())
  165.                           search.SetCaseSensitive( FALSE );
  166.                        else
  167.                           search.SetCaseSensitive( TRUE );
  168.                     }
  169.                     break;
  170.               }
  171.             break;
  172.      }
  173. }
  174.  
  175.  
  176. BOOL SearchDialog :: DoCommand( LONG com )
  177. {
  178.    switch( com )
  179.      {
  180.         case PUSH_CANCEL:
  181.            delete this;
  182.            break;
  183.         case PUSH_REPLACE:
  184.            {
  185.               XString buffer;
  186.               GetWindow( ENTRY_REPLACE )->GetText( &buffer );
  187.               mle->InsertString( buffer );
  188.            }
  189.            break;
  190.         case PUSH_SEARCH:
  191.            {
  192.               XString buffer;
  193.               GetWindow( ENTRY_SEARCH )->GetText( &buffer );
  194.               search.SetSearchItem( buffer );
  195.               GetWindow( ENTRY_REPLACE )->GetText( &buffer );
  196.               search.SetReplaceItem( buffer );
  197.               LONG start, end;
  198.               mle->GetSelection( start, end);
  199.               if(start > end )
  200.                  end = start;
  201.               search.SetStartPoint( end );
  202.               XCheckBox * c = (XCheckBox*) GetWindow( CHECK_REPLACE );
  203.               if( c->IsSelected())
  204.                  search.SetReplaceAll( TRUE );
  205.               else
  206.                  search.SetReplaceAll( FALSE );
  207.               if( mle->Search( &search ) )
  208.                  mle->Activate();
  209.               else
  210.                  XMessageBox( "pattern not found!", "Search", MB_OK|MB_ICONEXCLAMATION, this);
  211.               break;
  212.            }
  213.      }
  214.    return TRUE;
  215. }
  216.  
  217.  
  218. /*this is our search-dialog (very rudimental). We construct it out of the resources (see sample.dlg).*/
  219. SearchDialog :: SearchDialog ( XMultiLineEdit * m, XResource * r, MyAppWindow * w): XFrameWindow( r, "Search...", defaultDialogStyle | FRM_CENTER,  NULL, NULL, TRUE)
  220. {
  221.    mle = m;
  222.    win = w;
  223.  
  224.    /*enable the checkbox "ignore case" */
  225.    XCheckBox * c = (XCheckBox*) GetWindow( CHECK_CASE);
  226.    c->Select();
  227. }
  228.  
  229.  
  230. /*the destructor is called automaticaly when the window is close*/
  231. MyAppWindow :: ~MyAppWindow()
  232. {
  233.    /*is there a serch-dialog open? */
  234.    if(dlg)
  235.       delete dlg; /* yes, kill it */
  236. }
  237.  
  238.  
  239. /* this is the overridden method DoCmmand from XFrameWindow. all commands */
  240. /* from the menu (or toolbars in later samples) will be placed here. */
  241. BOOL MyAppWindow :: DoCommand( LONG command )
  242. {
  243.    switch ( command )
  244.       {
  245.          //default clipboard actions
  246.          case IDM_PASTE:
  247.             mle->Paste();
  248.             break;
  249.          case IDM_COPY:
  250.             mle->Copy();
  251.             break;
  252.          case IDM_CUT:
  253.             mle->Cut();
  254.             break;
  255.          case IDM_CLEAR:
  256.             mle->Clear();
  257.             break;
  258.          case IDM_FONT:
  259.             {
  260.                //select a new font for the MLE
  261.                XFontDialog dlg( this );
  262.                if( dlg.GetCommand() == USER_OK)
  263.                   {
  264.                      XString buffer;
  265.                      LONG s = dlg.GetFontSize();
  266.                      dlg.GetFontName( &buffer );
  267.                      mle->SetFont(buffer, s );
  268.                   }
  269.             }
  270.             break;
  271.          case IDM_SEARCH:
  272.             {
  273.                //open a search dialog
  274.                if( dlg ) //a dialog is already existing
  275.                   dlg->Activate();
  276.                else //create a new dialog
  277.                   {
  278.                      MyThread * t = (MyThread*) GetProcess();
  279.                      XResource newRes( DIALOG_SEARCH, t->resLib);
  280.                      dlg = new SearchDialog( mle, &newRes, this);
  281.                   }
  282.             }
  283.             break;
  284.          case IDM_OPEN:
  285.            {
  286.                /* display the filedialog defined by the system */
  287.                /* set the file-suffix and title of the dialog */
  288.                XFileDialog fileDlg(this, "*.TXT", NULL, NULL, FD_OPEN | FD_CENTER | FD_MULTIPLESEL);
  289.  
  290.                /* the user selected a file */
  291.                if( fileDlg.GetCommand() == USER_OK)
  292.                  {
  293.                     XString fileName;
  294.                     SHORT i, files = fileDlg.GetFileCount();  //how much files are selected?
  295.                     for(i=0; i < files; i++)
  296.                        {
  297.                           fileDlg.GetFileName( &fileName, i );  //get filename and path for every file
  298.                           LoadFile( fileName);                  //load the file
  299.                        }
  300.                  }
  301.             }
  302.             break;
  303.          case IDM_CLOSE:
  304.             /* the user selected close, so we try to close the window */
  305.             /* the (overridden) method QueryForClose is called automaticaly (see below)*/
  306.             delete this;
  307.             break;
  308.          case IDM_SAVE:
  309.             SaveFile();
  310.             break;
  311.        }
  312.    return TRUE;
  313. }
  314.  
  315.  
  316. /* when contents of window-controls change, we will get an event of the class */
  317. /* XControlEvent where we can ask for information about the event and the sending */
  318. /* window. in later examples the other types of events  will be shown */
  319. void MyMLE :: DoControl( XControlEvent * event )
  320. {
  321.    //ask for the id of the sending window and the type of event
  322.    if( event->GetEventID() == WIN_CHANGED && owner->loading == FALSE)
  323.       {
  324.          //sender is the MLE, event is that the text will be changed
  325.          if( owner->saved == TRUE)
  326.             {
  327.                XString s;
  328.                owner->GetText( &s );
  329.                s += " - changed";
  330.                owner->SetText( s );
  331.                owner->saved = FALSE;
  332.             }
  333.        }
  334. }
  335.  
  336.  
  337. /* this is an overridden method of XFrameWindow, it is called if the user try to close the */
  338. /* framewindow with the close-button or with ALT-F4. Return TRUE if the window can be closed, */
  339. /* otherwise return FALSE */
  340. BOOL MyAppWindow :: QueryForClose( void )
  341. {
  342.    if(saved == FALSE)    //text changed
  343.       {
  344.          XMessageBox msb( "Text changed - discard?", "Close Window", MB_YESNO|MB_WARNING|MB_MOVEABLE);
  345.          if( msb.GetCommand() == MBID_NO)
  346.             return FALSE;  //don∩t close the window
  347.       }
  348.   return TRUE;
  349. }
  350.  
  351.  
  352. /* load a file */
  353. BOOL MyAppWindow :: LoadFile ( char * p)
  354. {
  355.    // is there already a file loaded or has the user entered some text?
  356.    if(loaded == FALSE && saved == TRUE)
  357.       {
  358.          //no, we load the file in the window of the current thread
  359.          XFile loadfile;
  360.  
  361.          /* now open the file, fail if given filename is not existing */
  362.          /* open the file for read-access, dont allow any other programm to use the file while it is open*/
  363.          if( loadfile.Open( p, XFILE_FAIL_IF_NEW | XFILE_OPEN_EXISTING, XFILE_SHARE_DENYWRITE | XFILE_READONLY ) == 0)
  364.            {
  365.               XString s;
  366.  
  367.               loading = TRUE;
  368.  
  369.               //how large is the file?
  370.               XFileInfo info;
  371.               loadfile.GetFileInfo( &info );
  372.               LONG size = info.GetFileSize();
  373.  
  374.               //read the complete file
  375.               loadfile.Read ( (PVOID) s.GetBuffer(info.GetFileSize() + 1), size);
  376.               s.ReleaseBuffer( info.GetFileSize() );
  377.  
  378.               //set the XString content to the mle
  379.               mle->SetText( s );
  380.               //dont∩forget to close the file
  381.               loadfile.Close();
  382.               loaded = TRUE;
  383.               path = p;
  384.               mle->SetFocus();
  385.               GetText( &s );
  386.               s+= " - ";
  387.               s+= p;
  388.               SetText( s );
  389.  
  390.               loading = FALSE;
  391.  
  392.               return TRUE;
  393.             }
  394.          else
  395.             {
  396.                XMessageBox( p, "couldn∩t open File!", MB_OK|MB_ERROR);
  397.                return FALSE;
  398.             }
  399.       }
  400.    else
  401.      {
  402.          //there is a file loaded, or the user has entered some text, so
  403.          // we create a new thread which will load the file
  404.          MyThread * th = new MyThread( p);
  405.          th->Run();
  406.          return TRUE;
  407.      }
  408. }
  409.  
  410.  
  411. BOOL MyAppWindow :: SaveFile( void )
  412. {
  413.    XFile savefile;
  414.    XString s;
  415.  
  416.    mle->GetText( &s );
  417.  
  418.    /* now open the file, create a new one if the given filename is not existing, otherwise overwrite */
  419.    /* it. open the file for write-access, dont allow any other programm to use the file while it is open*/
  420.    if( savefile.Open( path, XFILE_CREATE_IF_NEW | XFILE_REPLACE_EXISTING, XFILE_SHARE_DENYNONE | XFILE_WRITEONLY, s.GetLength()) == 0)
  421.       {
  422.          /* set the file-cursor to the beginning of the file */
  423.          savefile.Seek( 0, FILE_BEGIN);
  424.  
  425.          /*save the string */
  426.          savefile.Write ( (char*) s, s.GetLength());
  427.  
  428.          /* close the file */
  429.          savefile.Close();
  430.          saved = TRUE;
  431.          return TRUE;
  432.       }
  433.    else
  434.       {
  435.          XMessageBox( "could not open file", "error", MB_OK| MB_ERROR);
  436.          return FALSE;
  437.       }
  438. }
  439.  
  440.  
  441. /* this is the overriden method Init() from XThread. here we can setup */
  442. /* the data for every thread and generate its objects*/
  443. void MyThread :: Init(void)
  444. {
  445.    resLib = new XResourceLibrary( this );  //create a resourcelibary out of the exe-file
  446.    XResource res( IDM_MAIN, resLib);
  447.    try
  448.    {
  449.       appWindow = new MyAppWindow( resLib, &res );  //create new framewindow (see above)
  450.    }
  451.    catch( XException& e)
  452.    {
  453.       e.ShowError();
  454.       exit(-1);
  455.    }
  456.  
  457.    if(iniFile.GetLength())                             //a file was specified in the constructur (it was in the command line)
  458.       appWindow->LoadFile(iniFile);        // so we load the file
  459. }
  460.  
  461.  
  462. /* our thread-constructor, p can be a pointer to a filename of a file to load */
  463. MyThread :: MyThread( char * p)
  464. {
  465.   if( p )
  466.      iniFile = p;
  467. }
  468.  
  469.  
  470. int main ( int argc, void ** argv)
  471. {
  472.    if( argc > 1)  //there were filenames in the commandline
  473.    {
  474.       SHORT i;
  475.       for(i=1; i < argc; i++)
  476.       {
  477.           MyThread * thread = new MyThread( (char*) argv[i] ); //start for every file a new thread
  478.           thread->Run();                                       //let the thread run
  479.       }
  480.    }
  481.    else
  482.    {
  483.       MyThread * thread = new MyThread();      //create a thread
  484.       thread->Run();                           //let the thread run
  485.    }
  486.  
  487.    XThread :: RunThreads();                       //let all threads work
  488.  
  489.    return 0;
  490. }
  491.