]> git.saurik.com Git - wxWidgets.git/blobdiff - samples/ogl/studio/csprint.cpp
Moved OGL to new locations.
[wxWidgets.git] / samples / ogl / studio / csprint.cpp
diff --git a/samples/ogl/studio/csprint.cpp b/samples/ogl/studio/csprint.cpp
new file mode 100644 (file)
index 0000000..6bf5dad
--- /dev/null
@@ -0,0 +1,320 @@
+/////////////////////////////////////////////////////////////////////////////
+// Name:        csprint.cpp
+// Purpose:     Printing and clipboard functionality
+// Author:      Julian Smart
+// Modified by:
+// Created:     12/07/98
+// RCS-ID:      $Id$
+// Copyright:   (c) Julian Smart
+// Licence:    wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifdef __GNUG__
+// #pragma implementation
+#endif
+
+// For compilers that support precompilation, includes "wx.h".
+#include <wx/wxprec.h>
+
+#ifdef __BORLANDC__
+#pragma hdrstop
+#endif
+
+#ifndef WX_PRECOMP
+#include <wx/wx.h>
+#endif
+
+#include <wx/wxexpr.h>
+#include <wx/clipbrd.h>
+
+#ifdef __WXMSW__
+#include <wx/metafile.h>
+#endif
+
+#include "studio.h"
+#include "doc.h"
+#include "shapes.h"
+#include "view.h"
+
+IMPLEMENT_DYNAMIC_CLASS(wxDiagramClipboard, wxDiagram)
+
+// Copy selection
+bool wxDiagramClipboard::Copy(wxDiagram* diagram)
+{
+    DeleteAllShapes();
+
+    return DoCopy(diagram, this, FALSE, NULL);
+}
+
+// Copy contents to the diagram, with new ids.
+
+bool wxDiagramClipboard::Paste(wxDiagram* diagram, wxDC* dc, int offsetX, int offsetY)
+{
+    return DoCopy(this, diagram, TRUE, dc, offsetX, offsetY);
+}
+
+// Universal copy function (to or from clipboard).
+// TODO:
+// Note that this only works for non-composites so far (nested shapes
+// don't have their old-to-new object mappings stored).
+// Also, lines don't yet get their attachment points moved to the new offset position
+// if they have more than 2 points.
+bool wxDiagramClipboard::DoCopy(wxDiagram* diagramFrom, wxDiagram* diagramTo, bool newIds,
+    wxDC* dc, int offsetX, int offsetY)
+{
+    OnStartCopy(diagramTo);
+
+    wxHashTable mapping(wxKEY_INTEGER);
+
+    // First copy all node shapes.
+    wxList* shapeList = diagramFrom->GetShapeList();
+    wxNode* node = shapeList->First();
+    while (node)
+    {
+        wxShape* shape = (wxShape*) node->Data();
+        if (((diagramFrom == this) || shape->Selected()) && !shape->IsKindOf(CLASSINFO(wxLineShape)))
+        {
+            wxShape* newShape = shape->CreateNewCopy();
+            newShape->GetLines().Clear();
+            if (newIds)
+            {
+                newShape->AssignNewIds();
+            }
+            mapping.Put((long) shape, (wxObject*) newShape);
+
+            newShape->SetX(newShape->GetX() + offsetX);
+            newShape->SetY(newShape->GetY() + offsetY);
+
+            OnAddShape(diagramTo, newShape, dc);
+
+        }
+        node = node->Next();
+    }
+
+    node = shapeList->First();
+    while (node)
+    {
+        wxShape* shape = (wxShape*) node->Data();
+        if (((diagramFrom == this) || shape->Selected()) && shape->IsKindOf(CLASSINFO(wxLineShape)))
+        {
+            wxLineShape* lineShape = (wxLineShape*) shape;
+            // Only copy a line if its ends are selected too.
+            if ((diagramFrom == this) || (lineShape->GetTo()->Selected() && lineShape->GetFrom()->Selected()))
+            {
+                wxLineShape* newShape = (wxLineShape*) shape->CreateNewCopy();
+                mapping.Put((long) shape, (wxObject*) newShape);
+
+                if (newIds)
+                    newShape->AssignNewIds();
+
+                wxShape* fromShape = (wxShape*) mapping.Get((long) lineShape->GetFrom());
+                wxShape* toShape = (wxShape*) mapping.Get((long) lineShape->GetTo());
+
+                wxASSERT_MSG( (fromShape != NULL), "Could not find 'from' shape");
+                wxASSERT_MSG( (toShape != NULL), "Could not find 'to' shape");
+
+                fromShape->AddLine(newShape, toShape, newShape->GetAttachmentFrom(),
+                  newShape->GetAttachmentTo());
+
+                OnAddShape(diagramTo, newShape, dc);
+
+            }
+        }
+        node = node->Next();
+    }
+
+    // Now make sure line ordering is correct
+    node = shapeList->First();
+    while (node)
+    {
+        wxShape* shape = (wxShape*) node->Data();
+        if (((diagramFrom == this) || shape->Selected()) && !shape->IsKindOf(CLASSINFO(wxLineShape)))
+        {
+            wxShape* newShape = (wxShape*) mapping.Get((long) shape);
+
+            // Make a list of all the new lines, in the same order as the old lines.
+            // Then apply the list of new lines to the shape.
+            wxList newLines;
+            wxNode* lineNode = shape->GetLines().First();
+            while (lineNode)
+            {
+                wxLineShape* lineShape = (wxLineShape*) lineNode->Data();
+                if ((diagramFrom == this) || (lineShape->GetTo()->Selected() && lineShape->GetFrom()->Selected()))
+                {
+                    wxLineShape* newLineShape = (wxLineShape*) mapping.Get((long) lineShape);
+
+                    wxASSERT_MSG( (newLineShape != NULL), "Could not find new line shape");
+
+                    newLines.Append(newLineShape);
+                }
+
+                lineNode = lineNode->Next();
+            }
+
+            if (newLines.Number() > 0)
+                newShape->ApplyAttachmentOrdering(newLines);
+        }
+        node = node->Next();
+    }
+
+    OnEndCopy(diagramTo);
+
+    return TRUE;
+}
+
+#ifdef __WXMSW__
+// Draw contents to a Windows metafile device context and a bitmap, and copy
+// these to the Windows clipboard
+bool wxDiagramClipboard::CopyToClipboard(double scale)
+{
+  // Make a metafile DC
+  wxMetaFileDC mfDC;
+  if (mfDC.Ok())
+  {
+    mfDC.SetUserScale(scale, scale);
+
+    // Draw on metafile DC
+    Redraw(mfDC);
+
+    int printWidth = mfDC.MaxX() - mfDC.MinX();
+    int printHeight = mfDC.MaxY() - mfDC.MinY();
+    int maxX = (int)mfDC.MaxX();
+    int maxY = (int)mfDC.MaxY();
+    wxMetaFile *mf = mfDC.Close();
+
+    // Set to a bitmap memory DC
+    wxBitmap *newBitmap = new wxBitmap((int)(maxX + 10), (int)(maxY + 10));
+    if (!newBitmap->Ok())
+    {
+      delete newBitmap;
+      
+      char buf[200];
+      sprintf(buf, "Sorry, could not allocate clipboard bitmap (%dx%d)", (maxX+10), (maxY+10));
+      wxMessageBox(buf, "Clipboard copy problem");
+      return FALSE;
+    }
+
+    wxMemoryDC memDC;
+    memDC.SelectObject(*newBitmap);
+    memDC.Clear();
+
+    // Now draw on memory bitmap DC
+    Redraw(memDC);
+
+    memDC.SelectObject(wxNullBitmap);
+
+    // Open clipboard and set the data
+    if (wxOpenClipboard())
+    {
+        wxEmptyClipboard();
+
+        // Copy the bitmap to the clipboard
+        wxSetClipboardData(wxDF_BITMAP, newBitmap, 0, 0);
+
+#if 0 // TODO: replace this code (wxEnhMetaFile doesn't have SetClipboard)
+        if (mf)
+        {
+            // Copy the metafile to the clipboard
+            // Allow a small margin
+            bool success = mf->SetClipboard((int)(mfDC.MaxX() + 15), (int)(mfDC.MaxY() + 15));
+        }
+#endif
+
+        // Close clipboard
+        wxCloseClipboard();
+    }
+    
+    delete newBitmap;
+    delete mf;
+
+  }
+  return TRUE;
+}
+#endif
+    // __WXMSW__
+
+// Override this to e.g. have the shape added through a Do/Undo command system.
+// By default, we'll just add it directly to the destination diagram.
+bool wxDiagramClipboard::OnAddShape(wxDiagram* diagramTo, wxShape* newShape, wxDC* dc)
+{
+    diagramTo->AddShape(newShape);
+
+    if (dc && (diagramTo != this))
+    {
+        newShape->Select(TRUE, dc);
+    }
+
+    return TRUE;
+}
+
+/*
+ * csDiagramClipboard
+ */
+
+IMPLEMENT_DYNAMIC_CLASS(csDiagramClipboard, wxDiagramClipboard)
+
+// Start/end copying
+bool csDiagramClipboard::OnStartCopy(wxDiagram* diagramTo)
+{
+    // Do nothing if copying to the clipboard
+    if (diagramTo == this)
+        return TRUE;
+
+    // Deselect all objects initially.
+
+    csDiagram* diagram = (csDiagram*) diagramTo;
+    csDiagramDocument* doc = diagram->GetDocument();
+    ((csDiagramView*)doc->GetFirstView())->SelectAll(FALSE);
+
+    m_currentCmd = new csDiagramCommand("Paste", doc);
+
+    return TRUE;
+}
+
+bool csDiagramClipboard::OnEndCopy(wxDiagram* diagramTo)
+{
+    // Do nothing if copying to the clipboard
+    if (diagramTo == this)
+        return TRUE;
+
+    csDiagram* diagram = (csDiagram*) diagramTo;
+    csDiagramDocument* doc = diagram->GetDocument();
+
+    if (m_currentCmd)
+    {
+        if (m_currentCmd->GetStates().Number() == 0)
+        {
+            delete m_currentCmd;
+        }
+        else
+        {
+            doc->GetCommandProcessor()->Submit(m_currentCmd);
+            m_currentCmd = NULL;
+        }
+    }
+    return TRUE;
+}
+
+// Use the command framework to add the shapes, if we're copying to a diagram and
+// not the clipboard.
+bool csDiagramClipboard::OnAddShape(wxDiagram* diagramTo, wxShape* newShape, wxDC* dc)
+{
+    if (diagramTo == this)
+    {
+        diagramTo->AddShape(newShape);
+    }
+    else
+    {
+        csDiagram* diagram = (csDiagram*) diagramTo;
+        csDiagramDocument* doc = diagram->GetDocument();
+
+        if (newShape->IsKindOf(CLASSINFO(wxLineShape)))
+            m_currentCmd->AddState(new csCommandState(ID_CS_ADD_LINE_SELECT, newShape, NULL));
+        else
+            m_currentCmd->AddState(new csCommandState(ID_CS_ADD_SHAPE_SELECT, newShape, NULL));
+    }
+
+    return TRUE;
+}
+
+