home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / wxos2240.zip / wxWindows-2.4.0 / contrib / samples / ogl / studio / csprint.cpp < prev    next >
C/C++ Source or Header  |  2001-10-30  |  9KB  |  321 lines

  1. /////////////////////////////////////////////////////////////////////////////
  2. // Name:        csprint.cpp
  3. // Purpose:     Printing and clipboard functionality
  4. // Author:      Julian Smart
  5. // Modified by:
  6. // Created:     12/07/98
  7. // RCS-ID:      $Id: csprint.cpp,v 1.2 2001/10/30 13:28:45 GT Exp $
  8. // Copyright:   (c) Julian Smart
  9. // Licence:       wxWindows licence
  10. /////////////////////////////////////////////////////////////////////////////
  11.  
  12. #ifdef __GNUG__
  13. // #pragma implementation
  14. #endif
  15.  
  16. // For compilers that support precompilation, includes "wx.h".
  17. #include "wx/wxprec.h"
  18.  
  19. #ifdef __BORLANDC__
  20. #pragma hdrstop
  21. #endif
  22.  
  23. #ifndef WX_PRECOMP
  24. #include <wx/wx.h>
  25. #endif
  26.  
  27. #include <wx/wxexpr.h>
  28. #include <wx/clipbrd.h>
  29.  
  30. #ifdef __WXMSW__
  31. #include <wx/metafile.h>
  32. #endif
  33.  
  34. #include "studio.h"
  35. #include "doc.h"
  36. #include "shapes.h"
  37. #include "view.h"
  38.  
  39. IMPLEMENT_DYNAMIC_CLASS(wxDiagramClipboard, wxDiagram)
  40.  
  41. // Copy selection
  42. bool wxDiagramClipboard::Copy(wxDiagram* diagram)
  43. {
  44.     DeleteAllShapes();
  45.  
  46.     return DoCopy(diagram, this, FALSE, NULL);
  47. }
  48.  
  49. // Copy contents to the diagram, with new ids.
  50.  
  51. bool wxDiagramClipboard::Paste(wxDiagram* diagram, wxDC* dc, int offsetX, int offsetY)
  52. {
  53.     return DoCopy(this, diagram, TRUE, dc, offsetX, offsetY);
  54. }
  55.  
  56. // Universal copy function (to or from clipboard).
  57. // TODO:
  58. // Note that this only works for non-composites so far (nested shapes
  59. // don't have their old-to-new object mappings stored).
  60. // Also, lines don't yet get their attachment points moved to the new offset position
  61. // if they have more than 2 points.
  62. bool wxDiagramClipboard::DoCopy(wxDiagram* diagramFrom, wxDiagram* diagramTo, bool newIds,
  63.     wxDC* dc, int offsetX, int offsetY)
  64. {
  65.     OnStartCopy(diagramTo);
  66.  
  67.     wxHashTable mapping(wxKEY_INTEGER);
  68.  
  69.     // First copy all node shapes.
  70.     wxList* shapeList = diagramFrom->GetShapeList();
  71.     wxNode* node = shapeList->First();
  72.     while (node)
  73.     {
  74.         wxShape* shape = (wxShape*) node->Data();
  75.         if (((diagramFrom == this) || shape->Selected()) && !shape->IsKindOf(CLASSINFO(wxLineShape)))
  76.         {
  77.             wxShape* newShape = shape->CreateNewCopy();
  78.             newShape->GetLines().Clear();
  79.             if (newIds)
  80.             {
  81.                 newShape->AssignNewIds();
  82.             }
  83.             mapping.Put((long) shape, (wxObject*) newShape);
  84.  
  85.             newShape->SetX(newShape->GetX() + offsetX);
  86.             newShape->SetY(newShape->GetY() + offsetY);
  87.  
  88.             OnAddShape(diagramTo, newShape, dc);
  89.  
  90.         }
  91.         node = node->Next();
  92.     }
  93.  
  94.     node = shapeList->First();
  95.     while (node)
  96.     {
  97.         wxShape* shape = (wxShape*) node->Data();
  98.         if (((diagramFrom == this) || shape->Selected()) && shape->IsKindOf(CLASSINFO(wxLineShape)))
  99.         {
  100.             wxLineShape* lineShape = (wxLineShape*) shape;
  101.             // Only copy a line if its ends are selected too.
  102.             if ((diagramFrom == this) || (lineShape->GetTo()->Selected() && lineShape->GetFrom()->Selected()))
  103.             {
  104.                 wxLineShape* newShape = (wxLineShape*) shape->CreateNewCopy();
  105.                 mapping.Put((long) shape, (wxObject*) newShape);
  106.  
  107.                 if (newIds)
  108.                     newShape->AssignNewIds();
  109.  
  110.                 wxShape* fromShape = (wxShape*) mapping.Get((long) lineShape->GetFrom());
  111.                 wxShape* toShape = (wxShape*) mapping.Get((long) lineShape->GetTo());
  112.  
  113.                 wxASSERT_MSG( (fromShape != NULL), "Could not find 'from' shape");
  114.                 wxASSERT_MSG( (toShape != NULL), "Could not find 'to' shape");
  115.  
  116.                 fromShape->AddLine(newShape, toShape, newShape->GetAttachmentFrom(),
  117.                   newShape->GetAttachmentTo());
  118.  
  119.                 OnAddShape(diagramTo, newShape, dc);
  120.  
  121.             }
  122.         }
  123.         node = node->Next();
  124.     }
  125.  
  126.     // Now make sure line ordering is correct
  127.     node = shapeList->First();
  128.     while (node)
  129.     {
  130.         wxShape* shape = (wxShape*) node->Data();
  131.         if (((diagramFrom == this) || shape->Selected()) && !shape->IsKindOf(CLASSINFO(wxLineShape)))
  132.         {
  133.             wxShape* newShape = (wxShape*) mapping.Get((long) shape);
  134.  
  135.             // Make a list of all the new lines, in the same order as the old lines.
  136.             // Then apply the list of new lines to the shape.
  137.             wxList newLines;
  138.             wxNode* lineNode = shape->GetLines().First();
  139.             while (lineNode)
  140.             {
  141.                 wxLineShape* lineShape = (wxLineShape*) lineNode->Data();
  142.                 if ((diagramFrom == this) || (lineShape->GetTo()->Selected() && lineShape->GetFrom()->Selected()))
  143.                 {
  144.                     wxLineShape* newLineShape = (wxLineShape*) mapping.Get((long) lineShape);
  145.  
  146.                     wxASSERT_MSG( (newLineShape != NULL), "Could not find new line shape");
  147.  
  148.                     newLines.Append(newLineShape);
  149.                 }
  150.  
  151.                 lineNode = lineNode->Next();
  152.             }
  153.  
  154.             if (newLines.Number() > 0)
  155.                 newShape->ApplyAttachmentOrdering(newLines);
  156.         }
  157.         node = node->Next();
  158.     }
  159.  
  160.     OnEndCopy(diagramTo);
  161.  
  162.     return TRUE;
  163. }
  164.  
  165. #ifdef __WXMSW__
  166. // Draw contents to a Windows metafile device context and a bitmap, and copy
  167. // these to the Windows clipboard
  168. bool wxDiagramClipboard::CopyToClipboard(double scale)
  169. {
  170.   // Make a metafile DC
  171.   wxMetaFileDC mfDC;
  172.   if (mfDC.Ok())
  173.   {
  174.     mfDC.SetUserScale(scale, scale);
  175.  
  176.     // Draw on metafile DC
  177.     Redraw(mfDC);
  178.  
  179.     int printWidth = mfDC.MaxX() - mfDC.MinX();
  180.     int printHeight = mfDC.MaxY() - mfDC.MinY();
  181.     int maxX = (int)mfDC.MaxX();
  182.     int maxY = (int)mfDC.MaxY();
  183.     wxMetaFile *mf = mfDC.Close();
  184.  
  185.     // Set to a bitmap memory DC
  186.     wxBitmap *newBitmap = new wxBitmap((int)(maxX + 10), (int)(maxY + 10));
  187.     if (!newBitmap->Ok())
  188.     {
  189.       delete newBitmap;
  190.       
  191.       char buf[200];
  192.       sprintf(buf, "Sorry, could not allocate clipboard bitmap (%dx%d)", (maxX+10), (maxY+10));
  193.       wxMessageBox(buf, "Clipboard copy problem");
  194.       return FALSE;
  195.     }
  196.  
  197.     wxMemoryDC memDC;
  198.     memDC.SelectObject(*newBitmap);
  199.     memDC.Clear();
  200.  
  201.     // Now draw on memory bitmap DC
  202.     Redraw(memDC);
  203.  
  204.     memDC.SelectObject(wxNullBitmap);
  205.  
  206.     // Open clipboard and set the data
  207.     if (wxOpenClipboard())
  208.     {
  209.         wxEmptyClipboard();
  210.  
  211.         // Copy the bitmap to the clipboard
  212.         wxSetClipboardData(wxDF_BITMAP, newBitmap, 0, 0);
  213.  
  214. #if 0 // TODO: replace this code (wxEnhMetaFile doesn't have SetClipboard)
  215.         if (mf)
  216.         {
  217.             // Copy the metafile to the clipboard
  218.             // Allow a small margin
  219.             bool success = mf->SetClipboard((int)(mfDC.MaxX() + 15), (int)(mfDC.MaxY() + 15));
  220.         }
  221. #endif
  222.  
  223.         // Close clipboard
  224.         wxCloseClipboard();
  225.     }
  226.     
  227.     delete newBitmap;
  228.     delete mf;
  229.  
  230.   }
  231.   return TRUE;
  232. }
  233. #endif
  234.     // __WXMSW__
  235.  
  236. // Override this to e.g. have the shape added through a Do/Undo command system.
  237. // By default, we'll just add it directly to the destination diagram.
  238. bool wxDiagramClipboard::OnAddShape(wxDiagram* diagramTo, wxShape* newShape, wxDC* dc)
  239. {
  240.     diagramTo->AddShape(newShape);
  241.  
  242.     if (dc && (diagramTo != this))
  243.     {
  244.         newShape->Select(TRUE, dc);
  245.     }
  246.  
  247.     return TRUE;
  248. }
  249.  
  250. /*
  251.  * csDiagramClipboard
  252.  */
  253.  
  254. IMPLEMENT_DYNAMIC_CLASS(csDiagramClipboard, wxDiagramClipboard)
  255.  
  256. // Start/end copying
  257. bool csDiagramClipboard::OnStartCopy(wxDiagram* diagramTo)
  258. {
  259.     // Do nothing if copying to the clipboard
  260.     if (diagramTo == this)
  261.         return TRUE;
  262.  
  263.     // Deselect all objects initially.
  264.  
  265.     csDiagram* diagram = (csDiagram*) diagramTo;
  266.     csDiagramDocument* doc = diagram->GetDocument();
  267.     ((csDiagramView*)doc->GetFirstView())->SelectAll(FALSE);
  268.  
  269.     m_currentCmd = new csDiagramCommand("Paste", doc);
  270.  
  271.     return TRUE;
  272. }
  273.  
  274. bool csDiagramClipboard::OnEndCopy(wxDiagram* diagramTo)
  275. {
  276.     // Do nothing if copying to the clipboard
  277.     if (diagramTo == this)
  278.         return TRUE;
  279.  
  280.     csDiagram* diagram = (csDiagram*) diagramTo;
  281.     csDiagramDocument* doc = diagram->GetDocument();
  282.  
  283.     if (m_currentCmd)
  284.     {
  285.         if (m_currentCmd->GetStates().Number() == 0)
  286.         {
  287.             delete m_currentCmd;
  288.         }
  289.         else
  290.         {
  291.             doc->GetCommandProcessor()->Submit(m_currentCmd);
  292.             m_currentCmd = NULL;
  293.         }
  294.     }
  295.     return TRUE;
  296. }
  297.  
  298. // Use the command framework to add the shapes, if we're copying to a diagram and
  299. // not the clipboard.
  300. bool csDiagramClipboard::OnAddShape(wxDiagram* diagramTo, wxShape* newShape, wxDC* dc)
  301. {
  302.     if (diagramTo == this)
  303.     {
  304.         diagramTo->AddShape(newShape);
  305.     }
  306.     else
  307.     {
  308.         csDiagram* diagram = (csDiagram*) diagramTo;
  309.         csDiagramDocument* doc = diagram->GetDocument();
  310.  
  311.         if (newShape->IsKindOf(CLASSINFO(wxLineShape)))
  312.             m_currentCmd->AddState(new csCommandState(ID_CS_ADD_LINE_SELECT, newShape, NULL));
  313.         else
  314.             m_currentCmd->AddState(new csCommandState(ID_CS_ADD_SHAPE_SELECT, newShape, NULL));
  315.     }
  316.  
  317.     return TRUE;
  318. }
  319.  
  320.  
  321.