]>
Commit | Line | Data |
---|---|---|
1fc25a89 JS |
1 | ///////////////////////////////////////////////////////////////////////////// |
2 | // Name: doc.cpp | |
3 | // Purpose: Implements document functionality | |
4 | // Author: Julian Smart | |
5 | // Modified by: | |
6 | // Created: 12/07/98 | |
7 | // RCS-ID: $Id$ | |
8 | // Copyright: (c) Julian Smart | |
2ba06d5a | 9 | // Licence: wxWindows licence |
1fc25a89 JS |
10 | ///////////////////////////////////////////////////////////////////////////// |
11 | ||
1fc25a89 | 12 | // For compilers that support precompilation, includes "wx.h". |
92a19c2e | 13 | #include "wx/wxprec.h" |
1fc25a89 JS |
14 | |
15 | #ifdef __BORLANDC__ | |
16 | #pragma hdrstop | |
17 | #endif | |
18 | ||
19 | #ifndef WX_PRECOMP | |
20 | #include <wx/wx.h> | |
21 | #endif | |
22 | ||
1fc25a89 JS |
23 | #include "studio.h" |
24 | #include "doc.h" | |
25 | #include "view.h" | |
26 | #include <wx/ogl/basicp.h> | |
27 | ||
28 | IMPLEMENT_DYNAMIC_CLASS(csDiagramDocument, wxDocument) | |
29 | ||
2b5dcd17 | 30 | #ifdef __VISUALC__ |
1fc25a89 JS |
31 | #pragma warning(disable:4355) |
32 | #endif | |
33 | ||
34 | csDiagramDocument::csDiagramDocument():m_diagram(this) | |
35 | { | |
36 | } | |
37 | ||
2b5dcd17 | 38 | #ifdef __VISUALC__ |
1fc25a89 JS |
39 | #pragma warning(default:4355) |
40 | #endif | |
41 | ||
42 | csDiagramDocument::~csDiagramDocument() | |
43 | { | |
44 | } | |
45 | ||
46 | bool csDiagramDocument::OnCloseDocument() | |
47 | { | |
48 | m_diagram.DeleteAllShapes(); | |
2ba06d5a | 49 | return true; |
1fc25a89 JS |
50 | } |
51 | ||
cecdcad1 | 52 | #if wxUSE_PROLOGIO |
1fc25a89 JS |
53 | bool csDiagramDocument::OnSaveDocument(const wxString& file) |
54 | { | |
1484b5cc | 55 | if (file == wxEmptyString) |
2ba06d5a | 56 | return false; |
1fc25a89 JS |
57 | |
58 | if (!m_diagram.SaveFile(file)) | |
59 | { | |
60 | wxString msgTitle; | |
1484b5cc | 61 | if (wxTheApp->GetAppName() != wxEmptyString) |
1fc25a89 JS |
62 | msgTitle = wxTheApp->GetAppName(); |
63 | else | |
1484b5cc | 64 | msgTitle = wxString(_T("File error")); |
1fc25a89 | 65 | |
1484b5cc | 66 | (void)wxMessageBox(_T("Sorry, could not open this file for saving."), msgTitle, wxOK | wxICON_EXCLAMATION, |
1fc25a89 | 67 | GetDocumentWindow()); |
2ba06d5a | 68 | return false; |
1fc25a89 JS |
69 | } |
70 | ||
2ba06d5a | 71 | Modify(false); |
1fc25a89 | 72 | SetFilename(file); |
2ba06d5a | 73 | return true; |
1fc25a89 | 74 | } |
2ba06d5a | 75 | |
1fc25a89 JS |
76 | bool csDiagramDocument::OnOpenDocument(const wxString& file) |
77 | { | |
78 | if (!OnSaveModified()) | |
2ba06d5a | 79 | return false; |
1fc25a89 JS |
80 | |
81 | wxString msgTitle; | |
1484b5cc | 82 | if (wxTheApp->GetAppName() != wxEmptyString) |
1fc25a89 JS |
83 | msgTitle = wxTheApp->GetAppName(); |
84 | else | |
1484b5cc | 85 | msgTitle = wxString(_T("File error")); |
1fc25a89 JS |
86 | |
87 | m_diagram.DeleteAllShapes(); | |
88 | if (!m_diagram.LoadFile(file)) | |
89 | { | |
1484b5cc | 90 | (void)wxMessageBox(_T("Sorry, could not open this file."), msgTitle, wxOK|wxICON_EXCLAMATION, |
1fc25a89 | 91 | GetDocumentWindow()); |
2ba06d5a | 92 | return false; |
1fc25a89 | 93 | } |
2ba06d5a WS |
94 | SetFilename(file, true); |
95 | Modify(false); | |
1fc25a89 | 96 | UpdateAllViews(); |
cecdcad1 | 97 | |
2ba06d5a | 98 | return true; |
1fc25a89 | 99 | } |
cecdcad1 | 100 | #endif // wxUSE_PROLOGIO |
2ba06d5a | 101 | |
1fc25a89 JS |
102 | |
103 | /* | |
104 | * Implementation of drawing command | |
105 | */ | |
106 | ||
107 | csDiagramCommand::csDiagramCommand(const wxString& name, csDiagramDocument *doc, | |
108 | csCommandState* onlyState): | |
2ba06d5a | 109 | wxCommand(true, name) |
1fc25a89 JS |
110 | { |
111 | m_doc = doc; | |
112 | ||
113 | if (onlyState) | |
114 | { | |
115 | AddState(onlyState); | |
116 | } | |
117 | } | |
118 | ||
119 | csDiagramCommand::~csDiagramCommand() | |
120 | { | |
36ca94a2 | 121 | wxObjectList::compatibility_iterator node = m_states.GetFirst(); |
1fc25a89 JS |
122 | while (node) |
123 | { | |
8552e6f0 | 124 | csCommandState* state = (csCommandState*) node->GetData(); |
1fc25a89 | 125 | delete state; |
8552e6f0 | 126 | node = node->GetNext(); |
1fc25a89 JS |
127 | } |
128 | } | |
129 | ||
130 | void csDiagramCommand::AddState(csCommandState* state) | |
131 | { | |
132 | state->m_doc = m_doc; | |
133 | // state->m_cmd = m_cmd; | |
134 | m_states.Append(state); | |
135 | } | |
136 | ||
137 | // Insert a state at the beginning of the list | |
138 | void csDiagramCommand::InsertState(csCommandState* state) | |
139 | { | |
140 | state->m_doc = m_doc; | |
141 | // state->m_cmd = m_cmd; | |
142 | m_states.Insert(state); | |
143 | } | |
144 | ||
145 | // Schedule all lines connected to the states to be cut. | |
146 | void csDiagramCommand::RemoveLines() | |
147 | { | |
36ca94a2 | 148 | wxObjectList::compatibility_iterator node = m_states.GetFirst(); |
1fc25a89 JS |
149 | while (node) |
150 | { | |
8552e6f0 | 151 | csCommandState* state = (csCommandState*) node->GetData(); |
1fc25a89 JS |
152 | wxShape* shape = state->GetShapeOnCanvas(); |
153 | wxASSERT( (shape != NULL) ); | |
154 | ||
36ca94a2 | 155 | wxObjectList::compatibility_iterator node1 = shape->GetLines().GetFirst(); |
1fc25a89 JS |
156 | while (node1) |
157 | { | |
8552e6f0 | 158 | wxLineShape *line = (wxLineShape *)node1->GetData(); |
1fc25a89 JS |
159 | if (!FindStateByShape(line)) |
160 | { | |
161 | csCommandState* newState = new csCommandState(ID_CS_CUT, NULL, line); | |
162 | InsertState(newState); | |
163 | } | |
164 | ||
8552e6f0 | 165 | node1 = node1->GetNext(); |
1fc25a89 | 166 | } |
8552e6f0 | 167 | node = node->GetNext(); |
1fc25a89 JS |
168 | } |
169 | } | |
170 | ||
171 | csCommandState* csDiagramCommand::FindStateByShape(wxShape* shape) | |
172 | { | |
36ca94a2 | 173 | wxObjectList::compatibility_iterator node = m_states.GetFirst(); |
1fc25a89 JS |
174 | while (node) |
175 | { | |
8552e6f0 | 176 | csCommandState* state = (csCommandState*) node->GetData(); |
1fc25a89 JS |
177 | if (shape == state->GetShapeOnCanvas() || shape == state->GetSavedState()) |
178 | return state; | |
8552e6f0 | 179 | node = node->GetNext(); |
1fc25a89 JS |
180 | } |
181 | return NULL; | |
182 | } | |
183 | ||
184 | bool csDiagramCommand::Do() | |
185 | { | |
36ca94a2 | 186 | wxObjectList::compatibility_iterator node = m_states.GetFirst(); |
1fc25a89 JS |
187 | while (node) |
188 | { | |
8552e6f0 | 189 | csCommandState* state = (csCommandState*) node->GetData(); |
1fc25a89 | 190 | if (!state->Do()) |
2ba06d5a | 191 | return false; |
8552e6f0 | 192 | node = node->GetNext(); |
1fc25a89 | 193 | } |
2ba06d5a | 194 | return true; |
1fc25a89 JS |
195 | } |
196 | ||
197 | bool csDiagramCommand::Undo() | |
198 | { | |
199 | // Undo in reverse order, so e.g. shapes get added | |
200 | // back before the lines do. | |
36ca94a2 | 201 | wxObjectList::compatibility_iterator node = m_states.GetLast(); |
1fc25a89 JS |
202 | while (node) |
203 | { | |
8552e6f0 | 204 | csCommandState* state = (csCommandState*) node->GetData(); |
1fc25a89 | 205 | if (!state->Undo()) |
2ba06d5a | 206 | return false; |
8552e6f0 | 207 | node = node->GetPrevious(); |
1fc25a89 | 208 | } |
2ba06d5a | 209 | return true; |
1fc25a89 JS |
210 | } |
211 | ||
212 | csCommandState::csCommandState(int cmd, wxShape* savedState, wxShape* shapeOnCanvas) | |
213 | { | |
214 | m_cmd = cmd; | |
215 | m_doc = NULL; | |
216 | m_savedState = savedState; | |
217 | m_shapeOnCanvas = shapeOnCanvas; | |
218 | m_linePositionFrom = 0; | |
219 | m_linePositionTo = 0; | |
220 | } | |
221 | ||
222 | csCommandState::~csCommandState() | |
223 | { | |
224 | if (m_savedState) | |
225 | { | |
226 | m_savedState->SetCanvas(NULL); | |
227 | delete m_savedState; | |
228 | } | |
229 | } | |
230 | ||
231 | bool csCommandState::Do() | |
232 | { | |
233 | switch (m_cmd) | |
234 | { | |
235 | case ID_CS_CUT: | |
236 | { | |
237 | // New state is 'nothing' - maybe pass shape ID to state so we know what | |
238 | // we're talking about. | |
239 | // Then save old shape in m_savedState (actually swap pointers) | |
240 | ||
241 | wxASSERT( (m_shapeOnCanvas != NULL) ); | |
242 | wxASSERT( (m_savedState == NULL) ); // new state will be 'nothing' | |
243 | wxASSERT( (m_doc != NULL) ); | |
244 | ||
245 | wxShapeCanvas* canvas = m_shapeOnCanvas->GetCanvas(); | |
246 | ||
247 | // In case this is a line | |
248 | wxShape* lineFrom = NULL; | |
249 | wxShape* lineTo = NULL; | |
250 | int attachmentFrom = 0, attachmentTo = 0; | |
251 | ||
252 | if (m_shapeOnCanvas->IsKindOf(CLASSINFO(wxLineShape))) | |
253 | { | |
254 | // Store the from/to info to save in the line shape | |
255 | wxLineShape* lineShape = (wxLineShape*) m_shapeOnCanvas; | |
256 | lineFrom = lineShape->GetFrom(); | |
257 | lineTo = lineShape->GetTo(); | |
258 | attachmentFrom = lineShape->GetAttachmentFrom(); | |
259 | attachmentTo = lineShape->GetAttachmentTo(); | |
260 | ||
261 | m_linePositionFrom = lineFrom->GetLinePosition(lineShape); | |
262 | m_linePositionTo = lineTo->GetLinePosition(lineShape); | |
263 | } | |
264 | ||
2ba06d5a WS |
265 | m_shapeOnCanvas->Select(false); |
266 | ((csDiagramView*) m_doc->GetFirstView())->SelectShape(m_shapeOnCanvas, false); | |
1fc25a89 JS |
267 | |
268 | m_shapeOnCanvas->Unlink(); | |
cecdcad1 | 269 | |
1fc25a89 JS |
270 | m_doc->GetDiagram()->RemoveShape(m_shapeOnCanvas); |
271 | ||
272 | m_savedState = m_shapeOnCanvas; | |
273 | ||
274 | if (m_savedState->IsKindOf(CLASSINFO(wxLineShape))) | |
275 | { | |
276 | // Restore the from/to info for future reference | |
277 | wxLineShape* lineShape = (wxLineShape*) m_savedState; | |
278 | lineShape->SetFrom(lineFrom); | |
279 | lineShape->SetTo(lineTo); | |
280 | lineShape->SetAttachments(attachmentFrom, attachmentTo); | |
281 | ||
282 | wxClientDC dc(canvas); | |
283 | canvas->PrepareDC(dc); | |
284 | ||
285 | lineFrom->MoveLinks(dc); | |
286 | lineTo->MoveLinks(dc); | |
287 | } | |
288 | ||
2ba06d5a | 289 | m_doc->Modify(true); |
1fc25a89 JS |
290 | m_doc->UpdateAllViews(); |
291 | break; | |
292 | } | |
293 | case ID_CS_ADD_SHAPE: | |
294 | case ID_CS_ADD_SHAPE_SELECT: | |
295 | { | |
296 | // The app has given the command state a new m_savedState | |
297 | // shape, which is the new shape to add to the canvas (but | |
298 | // not actually added until this point). | |
299 | // The new 'saved state' is therefore 'nothing' since there | |
300 | // was nothing there before. | |
301 | ||
302 | wxASSERT( (m_shapeOnCanvas == NULL) ); | |
303 | wxASSERT( (m_savedState != NULL) ); | |
304 | wxASSERT( (m_doc != NULL) ); | |
305 | ||
306 | m_shapeOnCanvas = m_savedState; | |
307 | m_savedState = NULL; | |
308 | ||
309 | m_doc->GetDiagram()->AddShape(m_shapeOnCanvas); | |
2ba06d5a | 310 | m_shapeOnCanvas->Show(true); |
1fc25a89 JS |
311 | |
312 | wxClientDC dc(m_shapeOnCanvas->GetCanvas()); | |
313 | m_shapeOnCanvas->GetCanvas()->PrepareDC(dc); | |
314 | ||
315 | csEvtHandler *handler = (csEvtHandler *)m_shapeOnCanvas->GetEventHandler(); | |
316 | m_shapeOnCanvas->FormatText(dc, handler->m_label); | |
317 | ||
318 | m_shapeOnCanvas->Move(dc, m_shapeOnCanvas->GetX(), m_shapeOnCanvas->GetY()); | |
319 | ||
320 | if (m_cmd == ID_CS_ADD_SHAPE_SELECT) | |
321 | { | |
2ba06d5a WS |
322 | m_shapeOnCanvas->Select(true, &dc); |
323 | ((csDiagramView*) m_doc->GetFirstView())->SelectShape(m_shapeOnCanvas, true); | |
1fc25a89 JS |
324 | } |
325 | ||
2ba06d5a | 326 | m_doc->Modify(true); |
1fc25a89 JS |
327 | m_doc->UpdateAllViews(); |
328 | break; | |
329 | } | |
330 | case ID_CS_ADD_LINE: | |
331 | case ID_CS_ADD_LINE_SELECT: | |
332 | { | |
333 | wxASSERT( (m_shapeOnCanvas == NULL) ); | |
334 | wxASSERT( (m_savedState != NULL) ); | |
335 | wxASSERT( (m_doc != NULL) ); | |
336 | ||
337 | wxLineShape *lineShape = (wxLineShape *)m_savedState; | |
338 | wxASSERT( (lineShape->GetFrom() != NULL) ); | |
339 | wxASSERT( (lineShape->GetTo() != NULL) ); | |
340 | ||
341 | m_shapeOnCanvas = m_savedState; | |
342 | m_savedState = NULL; | |
343 | ||
344 | m_doc->GetDiagram()->AddShape(lineShape); | |
345 | ||
346 | lineShape->GetFrom()->AddLine(lineShape, lineShape->GetTo(), | |
347 | lineShape->GetAttachmentFrom(), lineShape->GetAttachmentTo()); | |
cecdcad1 | 348 | |
2ba06d5a | 349 | lineShape->Show(true); |
1fc25a89 JS |
350 | |
351 | wxClientDC dc(lineShape->GetCanvas()); | |
352 | lineShape->GetCanvas()->PrepareDC(dc); | |
353 | ||
354 | // It won't get drawn properly unless you move both | |
355 | // connected images | |
356 | lineShape->GetFrom()->Move(dc, lineShape->GetFrom()->GetX(), lineShape->GetFrom()->GetY()); | |
357 | lineShape->GetTo()->Move(dc, lineShape->GetTo()->GetX(), lineShape->GetTo()->GetY()); | |
358 | ||
359 | if (m_cmd == ID_CS_ADD_LINE_SELECT) | |
360 | { | |
2ba06d5a WS |
361 | lineShape->Select(true, &dc); |
362 | ((csDiagramView*) m_doc->GetFirstView())->SelectShape(m_shapeOnCanvas, true); | |
1fc25a89 JS |
363 | } |
364 | ||
2ba06d5a | 365 | m_doc->Modify(true); |
1fc25a89 JS |
366 | m_doc->UpdateAllViews(); |
367 | break; | |
368 | } | |
369 | case ID_CS_CHANGE_BACKGROUND_COLOUR: | |
370 | case ID_CS_MOVE: | |
371 | case ID_CS_SIZE: | |
372 | case ID_CS_EDIT_PROPERTIES: | |
373 | case ID_CS_FONT_CHANGE: | |
374 | case ID_CS_ARROW_CHANGE: | |
375 | case ID_CS_ROTATE_CLOCKWISE: | |
376 | case ID_CS_ROTATE_ANTICLOCKWISE: | |
377 | case ID_CS_CHANGE_LINE_ORDERING: | |
378 | case ID_CS_CHANGE_LINE_ATTACHMENT: | |
379 | case ID_CS_ALIGN: | |
380 | case ID_CS_NEW_POINT: | |
381 | case ID_CS_CUT_POINT: | |
382 | case ID_CS_MOVE_LINE_POINT: | |
383 | case ID_CS_STRAIGHTEN: | |
384 | case ID_CS_MOVE_LABEL: | |
385 | { | |
386 | // At this point we have been given a new shape | |
387 | // just like the old one but with a changed colour. | |
388 | // It's now time to apply that change to the | |
389 | // shape on the canvas, saving the old state. | |
390 | // NOTE: this is general enough to work with MOST attribute | |
391 | // changes! | |
392 | ||
393 | wxASSERT( (m_shapeOnCanvas != NULL) ); | |
394 | wxASSERT( (m_savedState != NULL) ); // This is the new shape with changed colour | |
395 | wxASSERT( (m_doc != NULL) ); | |
396 | ||
397 | wxClientDC dc(m_shapeOnCanvas->GetCanvas()); | |
398 | m_shapeOnCanvas->GetCanvas()->PrepareDC(dc); | |
399 | ||
400 | bool isSelected = m_shapeOnCanvas->Selected(); | |
401 | if (isSelected) | |
2ba06d5a | 402 | m_shapeOnCanvas->Select(false, & dc); |
1fc25a89 JS |
403 | |
404 | if (m_cmd == ID_CS_SIZE || m_cmd == ID_CS_ROTATE_CLOCKWISE || m_cmd == ID_CS_ROTATE_ANTICLOCKWISE || | |
405 | m_cmd == ID_CS_CHANGE_LINE_ORDERING || m_cmd == ID_CS_CHANGE_LINE_ATTACHMENT) | |
406 | { | |
407 | m_shapeOnCanvas->Erase(dc); | |
408 | } | |
409 | ||
410 | // TODO: make sure the ID is the same. Or, when applying the new state, | |
411 | // don't change the original ID. | |
412 | wxShape* tempShape = m_shapeOnCanvas->CreateNewCopy(); | |
413 | ||
414 | // Apply the saved state to the shape on the canvas, by copying. | |
415 | m_savedState->CopyWithHandler(*m_shapeOnCanvas); | |
416 | ||
417 | // Delete this state now it's been used (m_shapeOnCanvas currently holds this state) | |
418 | delete m_savedState; | |
419 | ||
420 | // Remember the previous state | |
421 | m_savedState = tempShape; | |
422 | ||
423 | // Redraw the shape | |
424 | ||
425 | if (m_cmd == ID_CS_MOVE || m_cmd == ID_CS_ROTATE_CLOCKWISE || m_cmd == ID_CS_ROTATE_ANTICLOCKWISE || | |
426 | m_cmd == ID_CS_ALIGN) | |
427 | { | |
428 | m_shapeOnCanvas->Move(dc, m_shapeOnCanvas->GetX(), m_shapeOnCanvas->GetY()); | |
429 | ||
430 | csEvtHandler *handler = (csEvtHandler *)m_shapeOnCanvas->GetEventHandler(); | |
431 | m_shapeOnCanvas->FormatText(dc, handler->m_label); | |
432 | m_shapeOnCanvas->Draw(dc); | |
433 | } | |
434 | else if (m_cmd == ID_CS_CHANGE_LINE_ORDERING) | |
435 | { | |
436 | m_shapeOnCanvas->MoveLinks(dc); | |
437 | } | |
438 | else if (m_cmd == ID_CS_CHANGE_LINE_ATTACHMENT) | |
439 | { | |
440 | wxLineShape *lineShape = (wxLineShape *)m_shapeOnCanvas; | |
441 | ||
442 | // Have to move both sets of links since we don't know which links | |
443 | // have been affected (unless we compared before and after states). | |
444 | lineShape->GetFrom()->MoveLinks(dc); | |
445 | lineShape->GetTo()->MoveLinks(dc); | |
446 | } | |
447 | else if (m_cmd == ID_CS_SIZE) | |
448 | { | |
449 | double width, height; | |
450 | m_shapeOnCanvas->GetBoundingBoxMax(&width, &height); | |
451 | ||
452 | m_shapeOnCanvas->SetSize(width, height); | |
453 | m_shapeOnCanvas->Move(dc, m_shapeOnCanvas->GetX(), m_shapeOnCanvas->GetY()); | |
454 | ||
2ba06d5a | 455 | m_shapeOnCanvas->Show(true); |
1fc25a89 JS |
456 | |
457 | // Recursively redraw links if we have a composite. | |
8552e6f0 | 458 | if (m_shapeOnCanvas->GetChildren().GetCount() > 0) |
2ba06d5a | 459 | m_shapeOnCanvas->DrawLinks(dc, -1, true); |
1fc25a89 JS |
460 | |
461 | m_shapeOnCanvas->GetEventHandler()->OnEndSize(width, height); | |
462 | } | |
463 | else if (m_cmd == ID_CS_EDIT_PROPERTIES || m_cmd == ID_CS_FONT_CHANGE) | |
464 | { | |
465 | csEvtHandler *handler = (csEvtHandler *)m_shapeOnCanvas->GetEventHandler(); | |
466 | m_shapeOnCanvas->FormatText(dc, handler->m_label); | |
467 | m_shapeOnCanvas->Draw(dc); | |
468 | } | |
469 | else | |
470 | { | |
471 | m_shapeOnCanvas->Draw(dc); | |
472 | } | |
473 | ||
474 | if (isSelected) | |
2ba06d5a | 475 | m_shapeOnCanvas->Select(true, & dc); |
cecdcad1 | 476 | |
2ba06d5a | 477 | m_doc->Modify(true); |
1fc25a89 JS |
478 | m_doc->UpdateAllViews(); |
479 | ||
480 | break; | |
481 | } | |
482 | } | |
2ba06d5a | 483 | return true; |
1fc25a89 JS |
484 | } |
485 | ||
486 | bool csCommandState::Undo() | |
487 | { | |
488 | switch (m_cmd) | |
489 | { | |
490 | case ID_CS_CUT: | |
491 | { | |
492 | wxASSERT( (m_savedState != NULL) ); | |
493 | wxASSERT( (m_doc != NULL) ); | |
494 | ||
495 | m_doc->GetDiagram()->AddShape(m_savedState); | |
496 | m_shapeOnCanvas = m_savedState; | |
497 | m_savedState = NULL; | |
498 | ||
499 | if (m_shapeOnCanvas->IsKindOf(CLASSINFO(wxLineShape))) | |
500 | { | |
501 | wxLineShape* lineShape = (wxLineShape*) m_shapeOnCanvas; | |
502 | lineShape->GetFrom()->AddLine(lineShape, lineShape->GetTo(), | |
503 | lineShape->GetAttachmentFrom(), lineShape->GetAttachmentTo(), | |
504 | m_linePositionFrom, m_linePositionTo); | |
505 | ||
506 | wxShapeCanvas* canvas = lineShape->GetFrom()->GetCanvas(); | |
507 | ||
508 | wxClientDC dc(canvas); | |
509 | canvas->PrepareDC(dc); | |
510 | ||
511 | lineShape->GetFrom()->MoveLinks(dc); | |
512 | lineShape->GetTo()->MoveLinks(dc); | |
513 | ||
514 | } | |
2ba06d5a | 515 | m_shapeOnCanvas->Show(true); |
1fc25a89 | 516 | |
2ba06d5a | 517 | m_doc->Modify(true); |
1fc25a89 JS |
518 | m_doc->UpdateAllViews(); |
519 | break; | |
520 | } | |
521 | case ID_CS_ADD_SHAPE: | |
522 | case ID_CS_ADD_LINE: | |
523 | case ID_CS_ADD_SHAPE_SELECT: | |
524 | case ID_CS_ADD_LINE_SELECT: | |
525 | { | |
526 | wxASSERT( (m_shapeOnCanvas != NULL) ); | |
527 | wxASSERT( (m_savedState == NULL) ); | |
528 | wxASSERT( (m_doc != NULL) ); | |
529 | ||
530 | // In case this is a line | |
531 | wxShape* lineFrom = NULL; | |
532 | wxShape* lineTo = NULL; | |
533 | int attachmentFrom = 0, attachmentTo = 0; | |
534 | ||
535 | if (m_shapeOnCanvas->IsKindOf(CLASSINFO(wxLineShape))) | |
536 | { | |
537 | // Store the from/to info to save in the line shape | |
538 | wxLineShape* lineShape = (wxLineShape*) m_shapeOnCanvas; | |
539 | lineFrom = lineShape->GetFrom(); | |
540 | lineTo = lineShape->GetTo(); | |
541 | attachmentFrom = lineShape->GetAttachmentFrom(); | |
542 | attachmentTo = lineShape->GetAttachmentTo(); | |
543 | } | |
544 | ||
545 | wxClientDC dc(m_shapeOnCanvas->GetCanvas()); | |
546 | m_shapeOnCanvas->GetCanvas()->PrepareDC(dc); | |
547 | ||
2ba06d5a WS |
548 | m_shapeOnCanvas->Select(false, &dc); |
549 | ((csDiagramView*) m_doc->GetFirstView())->SelectShape(m_shapeOnCanvas, false); | |
1fc25a89 JS |
550 | m_doc->GetDiagram()->RemoveShape(m_shapeOnCanvas); |
551 | m_shapeOnCanvas->Unlink(); // Unlinks the line, if it is a line | |
552 | ||
553 | if (m_shapeOnCanvas->IsKindOf(CLASSINFO(wxLineShape))) | |
554 | { | |
555 | // Restore the from/to info for future reference | |
556 | wxLineShape* lineShape = (wxLineShape*) m_shapeOnCanvas; | |
557 | lineShape->SetFrom(lineFrom); | |
558 | lineShape->SetTo(lineTo); | |
559 | lineShape->SetAttachments(attachmentFrom, attachmentTo); | |
560 | } | |
561 | ||
562 | m_savedState = m_shapeOnCanvas; | |
563 | m_shapeOnCanvas = NULL; | |
564 | ||
2ba06d5a | 565 | m_doc->Modify(true); |
1fc25a89 JS |
566 | m_doc->UpdateAllViews(); |
567 | break; | |
568 | } | |
569 | case ID_CS_CHANGE_BACKGROUND_COLOUR: | |
570 | case ID_CS_MOVE: | |
571 | case ID_CS_SIZE: | |
572 | case ID_CS_EDIT_PROPERTIES: | |
573 | case ID_CS_FONT_CHANGE: | |
574 | case ID_CS_ARROW_CHANGE: | |
575 | case ID_CS_ROTATE_CLOCKWISE: | |
576 | case ID_CS_ROTATE_ANTICLOCKWISE: | |
577 | case ID_CS_CHANGE_LINE_ORDERING: | |
578 | case ID_CS_CHANGE_LINE_ATTACHMENT: | |
579 | case ID_CS_ALIGN: | |
580 | case ID_CS_NEW_POINT: | |
581 | case ID_CS_CUT_POINT: | |
582 | case ID_CS_MOVE_LINE_POINT: | |
583 | case ID_CS_STRAIGHTEN: | |
584 | case ID_CS_MOVE_LABEL: | |
585 | { | |
586 | // Exactly like the Do case; we're just swapping states. | |
587 | Do(); | |
588 | break; | |
589 | } | |
590 | } | |
591 | ||
2ba06d5a | 592 | return true; |
1fc25a89 JS |
593 | } |
594 |