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