]> git.saurik.com Git - wxWidgets.git/blob - utils/ogl/samples/studio/csprint.cpp
Added dummy OnIdle to wxWindow in wxGTK; doc tweaks
[wxWidgets.git] / utils / ogl / samples / studio / csprint.cpp
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
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 (mf)
215 {
216 // Copy the metafile to the clipboard
217 // Allow a small margin
218 bool success = mf->SetClipboard((int)(mfDC.MaxX() + 15), (int)(mfDC.MaxY() + 15));
219 }
220
221 // Close clipboard
222 wxCloseClipboard();
223 }
224
225 delete newBitmap;
226 delete mf;
227
228 }
229 return TRUE;
230 }
231 #endif
232 // __WXMSW__
233
234 // Override this to e.g. have the shape added through a Do/Undo command system.
235 // By default, we'll just add it directly to the destination diagram.
236 bool wxDiagramClipboard::OnAddShape(wxDiagram* diagramTo, wxShape* newShape, wxDC* dc)
237 {
238 diagramTo->AddShape(newShape);
239
240 if (dc && (diagramTo != this))
241 {
242 newShape->Select(TRUE, dc);
243 }
244
245 return TRUE;
246 }
247
248 /*
249 * csDiagramClipboard
250 */
251
252 IMPLEMENT_DYNAMIC_CLASS(csDiagramClipboard, wxDiagramClipboard)
253
254 // Start/end copying
255 bool csDiagramClipboard::OnStartCopy(wxDiagram* diagramTo)
256 {
257 // Do nothing if copying to the clipboard
258 if (diagramTo == this)
259 return TRUE;
260
261 // Deselect all objects initially.
262
263 csDiagram* diagram = (csDiagram*) diagramTo;
264 csDiagramDocument* doc = diagram->GetDocument();
265 ((csDiagramView*)doc->GetFirstView())->SelectAll(FALSE);
266
267 m_currentCmd = new csDiagramCommand("Paste", doc);
268
269 return TRUE;
270 }
271
272 bool csDiagramClipboard::OnEndCopy(wxDiagram* diagramTo)
273 {
274 // Do nothing if copying to the clipboard
275 if (diagramTo == this)
276 return TRUE;
277
278 csDiagram* diagram = (csDiagram*) diagramTo;
279 csDiagramDocument* doc = diagram->GetDocument();
280
281 if (m_currentCmd)
282 {
283 if (m_currentCmd->GetStates().Number() == 0)
284 {
285 delete m_currentCmd;
286 }
287 else
288 {
289 doc->GetCommandProcessor()->Submit(m_currentCmd);
290 m_currentCmd = NULL;
291 }
292 }
293 return TRUE;
294 }
295
296 // Use the command framework to add the shapes, if we're copying to a diagram and
297 // not the clipboard.
298 bool csDiagramClipboard::OnAddShape(wxDiagram* diagramTo, wxShape* newShape, wxDC* dc)
299 {
300 if (diagramTo == this)
301 {
302 diagramTo->AddShape(newShape);
303 }
304 else
305 {
306 csDiagram* diagram = (csDiagram*) diagramTo;
307 csDiagramDocument* doc = diagram->GetDocument();
308
309 if (newShape->IsKindOf(CLASSINFO(wxLineShape)))
310 m_currentCmd->AddState(new csCommandState(ID_CS_ADD_LINE_SELECT, newShape, NULL));
311 else
312 m_currentCmd->AddState(new csCommandState(ID_CS_ADD_SHAPE_SELECT, newShape, NULL));
313 }
314
315 return TRUE;
316 }
317
318