]> git.saurik.com Git - wxWidgets.git/blame_incremental - contrib/samples/ogl/studio/csprint.cpp
Tools
[wxWidgets.git] / contrib / samples / ogl / studio / csprint.cpp
... / ...
CommitLineData
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$
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
39IMPLEMENT_DYNAMIC_CLASS(wxDiagramClipboard, wxDiagram)
40
41// Copy selection
42bool 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
51bool 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.
62bool 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
168bool 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.
238bool 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
254IMPLEMENT_DYNAMIC_CLASS(csDiagramClipboard, wxDiagramClipboard)
255
256// Start/end copying
257bool 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
274bool 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.
300bool 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