home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / VSCPPv8.zip / VACPP / IBMCPP / samples / IOC / CLIPBRD / CLIPBRD.CPP < prev    next >
Text File  |  1995-05-01  |  18KB  |  426 lines

  1. /******************************************************************************/
  2. /* Clipboard Sample Program:                                                  */
  3. /*                                                                            */
  4. /* COPYRIGHT: Copyright (C) International Business Machines Corp., 1992,1993. */
  5. /*                                                                            */
  6. /* DISCLAIMER OF WARRANTIES:                                                  */
  7. /*   The following [enclosed] code is sample code created by IBM              */
  8. /*   Corporation.  This sample code is not part of any standard IBM product   */
  9. /*   and is provided to you solely for the purpose of assisting you in the    */
  10. /*   development of your applications.  The code is provided "AS IS",         */
  11. /*   without warranty of any kind.  IBM shall not be liable for any damages   */
  12. /*   arising out of your use of the sample code, even if they have been       */
  13. /*   advised of the possibility of such damages.                              */
  14. /******************************************************************************/
  15.  
  16. #ifndef _IBASE_                         //  Ensure ibase.hpp is included
  17.   #include <ibase.hpp>                  //  since that is where IC_<environ>
  18. #endif                                  //  is defined.
  19. #include <iframe.hpp>
  20. #include <ipopmenu.hpp>
  21. #include <iclipbrd.hpp>
  22. #include <icliphdr.hpp>
  23. #include <icmdhdr.hpp>
  24. #include <icnr.hpp>
  25. #include <icnrolst.hpp>
  26. #include <istring.hpp>
  27. #include <istparse.hpp>
  28. #include <iexcept.hpp>
  29. #include <itrace.hpp>
  30. #include "clipbrd.h"
  31. #include "clipbrd.hpp"
  32.  
  33. // Define our static Separator objects:
  34. //   The first separates fields in the Department object string;
  35. //   the second separates multiple Department object strings.
  36. const IString Department::separator("~");
  37. const IString ContainerCutPasteHandler::separator("^");
  38.  
  39. // Define the private format of our Department object.
  40. const IString Department::renderedFormat("Department_rendered");
  41.  
  42.  
  43. //*************************************************************************
  44. // main  - Application entry point                                        *
  45. //*************************************************************************
  46. int main()
  47. {
  48.   IFrameWindow frame("Container Clipboard Sample", WND_MAIN);
  49.  
  50.   // Create the details view container with columns that
  51.   // displays the Department name and address.
  52.   IContainerControl container(0x8008, &frame, &frame);
  53.   IContainerColumn name(IContainerColumn::isIconViewText);
  54.   IContainerColumn address( Department::offsetOfAddress());
  55.   container.addColumn(&name);
  56.   container.addColumn(&address);
  57.  
  58.   // Create the Department objects and add them to
  59.   // the container.
  60.   Department* department;
  61.   department = new Department("Accounting", "Midwest Branch");
  62.   container.addObject(department);
  63.   department = new Department("Sales", "Atlantic Coast Branch");
  64.   container.addObject(department);
  65.  
  66.   // Create the cut and paste handler (the handlers are
  67.   // added in the constructor).
  68.   ContainerCutPasteHandler handler(container);
  69.  
  70.   // Enable extended selection, switch to details view, and
  71.   // give the container the focus.
  72.   container.setExtendedSelection();
  73.   container.showDetailsView();
  74.   container.setFocus();
  75.  
  76.   // Add an icon to the frame, put the container in the
  77.   // client, and show the frame window.
  78.   frame.setIcon( frame.id() );
  79.   frame.setClient(&container);
  80.   frame.show();
  81.  
  82.   // Start processing events.
  83.   IApplication::current().run();
  84.  
  85.   return 0;
  86. }
  87.  
  88.  
  89. /*------------------------------------------------------------------------------
  90. | ContainerCutPasteHandler::ContainerCutPasteHandler                           |
  91. |                                                                              |
  92. | Construct the handlers, register our private clipboard format, and          |
  93. | attach the handlers to the container.                                        |
  94. ------------------------------------------------------------------------------*/
  95. ContainerCutPasteHandler :: ContainerCutPasteHandler ( IContainerControl& container)
  96.       : cnr(container),
  97.         objectList(new ICnrObjectSet())
  98. {
  99.   // Enable the command, menu, and clipboard handlers.
  100.   ICommandHandler::handleEventsFor(&container);
  101.   ICnrMenuHandler::handleEventsFor(&container);
  102.   IClipboardHandler::handleEventsFor(&container);
  103.  
  104.   // Register the Department object's private format.
  105.   IClipboard::registerFormat( Department::renderedFormat);
  106. }
  107.  
  108.  
  109. /*------------------------------------------------------------------------------
  110. | ContainerCutPasteHandler::command                                            |
  111. |                                                                              |
  112. | Handle the command events associated with the clipboard (Cut, Copy,          |
  113. | and Paste).                                                                  |
  114. ------------------------------------------------------------------------------*/
  115. IBase::Boolean ContainerCutPasteHandler::command ( ICommandEvent& event)
  116. {
  117.   switch(event.commandId())
  118.   {
  119.     case MI_CUT           :
  120.     case MI_COPY          :
  121.     {
  122.       // Empty the clipboard to establish ownership
  123.       IClipboard clipboard(event.window()->handle());
  124.       clipboard.empty();
  125.  
  126.       // Find the cursored object in the container.
  127.       Department* cursoredObject = (Department*)(container().cursoredObject());
  128.  
  129.       // Utilize delayed rendering to put the data of the private
  130.       // format on the clipboard.  Maintain an "objectList" collection
  131.       // to keep track of the objects cut or copied onto the clipboard.
  132.       // Then, use the collection to render objects in the private
  133.       // format.  Store text data for the objects so that applications
  134.       // that don't support the private format can paste the data into a
  135.       // text editor.
  136.  
  137.       // Clear the collection used to keep track of clipboard objects.
  138.       objectList->removeAll();
  139.  
  140.       // If the cursored object is selected, loop through all other
  141.       // selected objects and store the objects in our set.
  142.       if (container().isSelected(cursoredObject))
  143.       {
  144.         unsigned long count = 0;
  145.         IString objectsAsText("");
  146.         IContainerControl::ObjectCursor cursor(container(), IContainerObject::selected);
  147.         for (cursor.setToFirst(); cursor.isValid(); cursor.setToNext())
  148.         {
  149.           count++;
  150.           Department* selectedObject = (Department*)(container().objectAt(cursor));
  151.           objectList->add(selectedObject);
  152.           objectsAsText = objectsAsText +  selectedObject->text();
  153.         }
  154.  
  155.         // Put the data on the clipboard.  We put our private
  156.         // format first since it has the most information.
  157.         // We use 0 for the data pointer of our private format
  158.         // because we want to delay the rendering until
  159.         // the paste operation.
  160.  
  161.         clipboard.setData(Department::renderedFormat, 0, 0);
  162.         clipboard.setText(objectsAsText);
  163.  
  164.         // If this is a Cut, put the data on the clipboard
  165.         // instead of using delayed rendering because we delete
  166.         // the object. Therefore we request the data
  167.         // to force the delayed rendering by our handler.
  168.         if (event.commandId() == MI_CUT)
  169.         {
  170.           char* data = (char*)clipboard.data(Department::renderedFormat);
  171.           container().deleteSelectedObjects();
  172.         }
  173.       }
  174.       else
  175.       {
  176.         // If the object is not selected, repeat the above procedure
  177.         // for the cursored object.
  178.         objectList->add(cursoredObject);
  179.  
  180.         // Put the data on the clipboard (requesting
  181.         // delayed rendering).
  182.         clipboard.setData(Department::renderedFormat, 0,0);
  183.  
  184.         // If this is a Cut request, force the ClipboardCutPasteHandler
  185.         // to render the data by requesting the data.  Then, delete the
  186.         // cursored object.
  187.         if (event.commandId() == MI_CUT) {
  188.           char* data = (char*)clipboard.data(Department::renderedFormat);
  189.           container().removeObject(cursoredObject);
  190.           delete cursoredObject;
  191.         }
  192.       }
  193.       return true;
  194.     }
  195.     case MI_PASTE         :
  196.     {
  197.       IClipboard clipboard(event.window()->handle());
  198.  
  199.       // If the clipboard has data of the private format,
  200.       // get the data and build objects from it.
  201.       // Note:  To see the text format of the data, paste
  202.       // from the clipboard using any text editor that
  203.       // supports the clipboard.
  204.       if (clipboard.hasData(Department::renderedFormat))
  205.       {
  206.          IString strCount, strObject, objectsAsString;
  207.  
  208.          // Query the data on the clipboard.
  209.          char* data = (char*)clipboard.data(Department::renderedFormat);
  210.  
  211.          // Parse the string into our data fields.
  212.          data >> strCount >> separator >> objectsAsString;
  213.  
  214.          // Extract the number of objects stored in the string.
  215.          unsigned long count = strCount.asUnsigned();
  216.  
  217.          // Turn refresh off to eliminate multiple painting.
  218.          container().setRefreshOff();
  219.  
  220.          // Construct new objects from the data.
  221.          for( int i=0; i<count; i++)
  222.          {
  223.            objectsAsString >> strObject >> separator >> objectsAsString;
  224.            Department* department = new Department();
  225.            department->initializeFromString(strObject);
  226.            container().addObject(department);
  227.          }
  228.  
  229.          // Enable refresh and refresh the container.
  230.          container().setRefreshOn();
  231.          container().refresh();
  232.       }
  233.       return true;
  234.     }
  235.   }
  236. return false;
  237. }
  238.  
  239.  
  240. /*------------------------------------------------------------------------------
  241. | ContainerCutPasteHandler::makePopUpMenu                                      |
  242. |                                                                              |
  243. | Create a pop-up menu with the clipboard actions.                             |
  244. ------------------------------------------------------------------------------*/
  245. IBase::Boolean ContainerCutPasteHandler::makePopUpMenu(IMenuEvent& event)
  246. {
  247.   IPopUpMenu* popUpMenu = new IPopUpMenu(CNR_POPUPMENU,
  248.                                          event.window());
  249.  
  250.   // Enable the allowable menu items in the pop-up menu.
  251.   if (popupMenuObject()) {
  252.     ((IContainerControl*)event.window())->setCursor(popupMenuObject());
  253.     popUpMenu->disableItem(MI_PASTE);
  254.   }
  255.   else
  256.   {
  257.     popUpMenu->disableItem(MI_CUT);
  258.     popUpMenu->disableItem(MI_COPY);
  259.   }
  260.  
  261.   //  Show the menu.
  262.   popUpMenu->setAutoDeleteObject();
  263.   popUpMenu->show(event.mousePosition());
  264.   return true;
  265. }
  266.  
  267. /*------------------------------------------------------------------------------
  268. | ContainerCutPasteHandler::clipboardEmptied                                   |
  269. |                                                                              |
  270. | This function is responsible for cleaning up data when the clipboard is      |
  271. | emptied and has nothing to do for now.                                       |
  272. ------------------------------------------------------------------------------*/
  273. IBase::Boolean ContainerCutPasteHandler::clipboardEmptied ( IEvent& )
  274. {
  275.   return true;
  276. }
  277.  
  278. /*------------------------------------------------------------------------------
  279. | ContainerCutPasteHandler::renderFormat                                       |
  280. |                                                                              |
  281. | Put our private format data on the clipboard.                                |
  282. ------------------------------------------------------------------------------*/
  283. IBase::Boolean ContainerCutPasteHandler::renderFormat( IEvent& event,
  284.                                                const IString&  format)
  285. {
  286.   // Use the handler's collection to find the Department objects
  287.   // whose data we need to put on the clipboard.
  288.   // Note:  If data gets copied to the clipboard for a Department
  289.   //        object and the object is deleted before the paste
  290.   //        operation, we will not be able to supply the object's
  291.   //        data.  If this is a problem, do not use delayed
  292.   //        rendering or post a message to the container telling
  293.   //        it to renderAllFormats whenever objects are deleted in
  294.   //        the container.
  295.   IClipboard clipboard(event.window()->handle());
  296.   if (clipboard.hasData(Department::renderedFormat))
  297.   {
  298.      // Cursor the objects and build the string.
  299.      ICnrObjectSet::Cursor cursor(*objectList);
  300.  
  301.      IString objectsAsString("");
  302.      unsigned long count = 0;
  303.  
  304.      // Loop through our collection and query the object for
  305.      // its data.
  306.      for( cursor.setToFirst(); cursor.isValid(); cursor.setToNext())
  307.      {
  308.        count++;
  309.        Department* department = (Department*)objectList->elementAt(cursor);
  310.  
  311.        // Document that no support is present for rendering objects
  312.        // after they are removed from the container.
  313.        IASSERTSTATE(container().containsObject(department));
  314.  
  315.        objectsAsString = objectsAsString + separator
  316.                                       + department->asString();
  317.      }
  318.      // Build the final string and put the data on the clipboard.
  319.      objectsAsString  =  IString(count) + objectsAsString;
  320.      clipboard.setData(Department::renderedFormat,
  321.                        (const char*)objectsAsString,
  322.                        objectsAsString.size()+1);
  323.   }
  324. return true;
  325.  
  326. }
  327.  
  328.  
  329. /*------------------------------------------------------------------------------
  330. | ContainerCutPasteHandler::renderAllFormats                                   |
  331. |                                                                              |
  332. | Pass this on to our function to render a single format since we only use     |
  333. | one format with delayed rendering.                                           |
  334. ------------------------------------------------------------------------------*/
  335. IBase::Boolean ContainerCutPasteHandler::renderAllFormats( IEvent& event)
  336. {
  337.   return renderFormat(event, Department::renderedFormat);
  338. }
  339.  
  340.  
  341. /*------------------------------------------------------------------------------
  342. | Department::name                                                             |
  343. |                                                                              |
  344. | Return the name of the Department object.                                    |
  345. ------------------------------------------------------------------------------*/
  346. IString Department::name( ) const
  347. {
  348.   return iconText();
  349. }
  350.  
  351. /*------------------------------------------------------------------------------
  352. | Department::address                                                          |
  353. |                                                                              |
  354. | Return the address of the Department object.                                 |
  355. ------------------------------------------------------------------------------*/
  356. IString Department::address( ) const
  357. {
  358.   return strAddress;
  359. }
  360.  
  361. /*------------------------------------------------------------------------------
  362. | Department::setName                                                          |
  363. |                                                                              |
  364. | Set the name of the Department object.                                       |
  365. ------------------------------------------------------------------------------*/
  366. Department& Department::setName( const IString& name)
  367. {
  368.   setIconText(name);
  369.   return *this;
  370. }
  371.  
  372. /*------------------------------------------------------------------------------
  373. | Department::setAddress                                                       |
  374. |                                                                              |
  375. | Set the address of the Department object.                                    |
  376. ------------------------------------------------------------------------------*/
  377. Department& Department::setAddress( const IString& address)
  378. {
  379.   strAddress = address;
  380.   return *this;
  381. }
  382.  
  383. /*------------------------------------------------------------------------------
  384. | Department::asString                                                         |
  385. |                                                                              |
  386. | Render the Department object as a String that we can later use to            |
  387. | reconstruct a Department object.                                             |
  388. ------------------------------------------------------------------------------*/
  389. IString Department::asString ( ) const
  390. {
  391.   IString strObject = name() + separator + address();
  392.   return strObject;
  393. }
  394.  
  395. /*------------------------------------------------------------------------------
  396. | Department::text                                                             |
  397. |                                                                              |
  398. | Render the Department object as a text string with Name formatted to         |
  399. | 30 characters, and address formatted to 50 characters with both              |
  400. | followed by a new line character.  Use this format for storing a plain       |
  401. | text format of our object on the clipboard.                                  |
  402. ------------------------------------------------------------------------------*/
  403. IString Department::text ( ) const
  404. {
  405.   IString strObject(name().subString(1,30) + address().subString(1,50) + "\n");
  406.   return strObject;
  407. }
  408.  
  409.  
  410. /*------------------------------------------------------------------------------
  411. | Department::initializeFromString                                             |
  412. |                                                                              |
  413. | Set the fields of the object by parsing the passed string.                   |
  414. ------------------------------------------------------------------------------*/
  415. Department& Department::initializeFromString ( const IString& renderedString )
  416. {
  417.   IString strName, strAddress;
  418.   renderedString >> strName >> separator >> strAddress;
  419.   setName (strName);
  420.   setAddress(strAddress);
  421.  
  422.   return *this;
  423. }
  424.  
  425.  
  426.