X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/dbeac4bd72c8604616919c89f0450899b182313a..306dfc2b3d49ca45445bdfb2164fe1eea45ab321:/utils/ogl/samples/studio/csprint.cpp diff --git a/utils/ogl/samples/studio/csprint.cpp b/utils/ogl/samples/studio/csprint.cpp new file mode 100644 index 0000000000..8006c2717f --- /dev/null +++ b/utils/ogl/samples/studio/csprint.cpp @@ -0,0 +1,318 @@ +///////////////////////////////////////////////////////////////////////////// +// 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 + +#ifdef __BORLANDC__ +#pragma hdrstop +#endif + +#ifndef WX_PRECOMP +#include +#endif + +#include +#include + +#ifdef __WXMSW__ +#include +#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 (mf) + { + // Copy the metafile to the clipboard + // Allow a small margin + bool success = mf->SetClipboard((int)(mfDC.MaxX() + 15), (int)(mfDC.MaxY() + 15)); + } + + // 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; +} + +