31 #include <wx/wxprec.h>
38 #include <wx/datetime.h>
39 #include <wx/clipbrd.h>
41 #include "model/route.h"
42 #include "model/routeman.h"
43 #include "model/select.h"
48 #include "ocpn_frame.h"
49 #include "routemanagerdialog.h"
63 isInsideUndoableAction =
false;
68 for (
unsigned int i = 0; i < undoStack.size(); i++) {
77 wxString UndoAction::Description() {
80 case Undo_CreateWaypoint:
81 descr = _(
"Create Mark");
83 case Undo_DeleteWaypoint:
84 descr = _(
"Delete Mark");
86 case Undo_MoveWaypoint:
87 descr = _(
"Move Waypoint");
89 case Undo_AppendWaypoint:
90 descr = _(
"Append Waypoint");
102 wxRealPoint* lastPoint = (wxRealPoint*)action->before[0];
103 lat = currentPoint->m_lat;
104 lon = currentPoint->m_lon;
105 currentPoint->m_lat = lastPoint->y;
106 currentPoint->m_lon = lastPoint->x;
110 selectable->m_slat = currentPoint->m_lat;
111 selectable->m_slon = currentPoint->m_lon;
113 if ((NULL != g_pMarkInfoDialog) && (g_pMarkInfoDialog->IsShown())) {
114 if (currentPoint == g_pMarkInfoDialog->GetRoutePoint())
115 g_pMarkInfoDialog->UpdateProperties(
true);
118 wxArrayPtrVoid* routeArray =
119 g_pRouteMan->GetRouteArrayContaining(currentPoint);
121 for (
unsigned int ir = 0; ir < routeArray->GetCount(); ir++) {
123 pr->FinalizeForRendering();
124 pr->UpdateSegmentDistances();
125 pConfig->UpdateRoute(pr);
133 pSelect->AddSelectableRoutePoint(point->m_lat, point->m_lon, point);
134 pConfig->AddNewWayPoint(point, -1);
135 if (NULL != pWayPointMan) pWayPointMan->AddRoutePoint(point);
136 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
137 pRouteManagerDialog->UpdateWptListCtrl();
142 pConfig->DeleteWayPoint(point);
143 pSelect->DeleteSelectablePoint(point, SELTYPE_ROUTEPOINT);
144 if (NULL != pWayPointMan) pWayPointMan->RemoveRoutePoint(point);
145 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
146 pRouteManagerDialog->UpdateWptListCtrl();
153 bool noRouteLeftToRedo =
false;
154 if ((route->GetnPoints() == 2) && (cc->m_routeState == 0))
155 noRouteLeftToRedo =
true;
157 g_pRouteMan->RemovePointFromRoute(point, route, cc->m_routeState);
158 gFrame->InvalidateAllGL();
160 if (action->beforeType[0] == Undo_IsOrphanded) {
161 pConfig->DeleteWayPoint(point);
162 pSelect->DeleteSelectablePoint(point, SELTYPE_ROUTEPOINT);
163 if (NULL != pWayPointMan) pWayPointMan->RemoveRoutePoint(point);
166 if (noRouteLeftToRedo) {
167 cc->undo->InvalidateRedo();
170 if(RouteManagerDialog::getInstanceFlag()){
171 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
172 pRouteManagerDialog->UpdateWptListCtrl();
175 if (cc->m_routeState > 1) {
177 cc->m_prev_pMousePoint = route->GetLastPoint();
178 cc->m_prev_rlat = cc->m_prev_pMousePoint->m_lat;
179 cc->m_prev_rlon = cc->m_prev_pMousePoint->m_lon;
180 route->m_lastMousePointIndex = route->GetnPoints();
188 if (action->beforeType[0] == Undo_IsOrphanded) {
189 pConfig->AddNewWayPoint(point, -1);
190 pSelect->AddSelectableRoutePoint(point->m_lat, point->m_lon, point);
193 RoutePoint* prevpoint = route->GetLastPoint();
195 route->AddPoint(point);
196 pSelect->AddSelectableRouteSegment(prevpoint->m_lat, prevpoint->m_lon,
197 point->m_lat, point->m_lon, prevpoint,
200 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
201 pRouteManagerDialog->UpdateWptListCtrl();
203 if (cc->m_routeState > 1) {
205 cc->m_prev_pMousePoint = route->GetLastPoint();
206 cc->m_prev_rlat = cc->m_prev_pMousePoint->m_lat;
207 cc->m_prev_rlon = cc->m_prev_pMousePoint->m_lon;
208 route->m_lastMousePointIndex = route->GetnPoints();
212 bool Undo::AnythingToUndo() {
return undoStack.size() > stackpointer; }
214 bool Undo::AnythingToRedo() {
return stackpointer > 0; }
216 UndoAction* Undo::GetNextUndoableAction() {
return undoStack[stackpointer]; }
219 return undoStack[stackpointer - 1];
222 void Undo::InvalidateRedo() {
223 if (stackpointer == 0)
return;
228 for (
unsigned int i = 0; i < stackpointer; i++) {
229 switch (undoStack[i]->type) {
230 case Undo_DeleteWaypoint:
231 undoStack[i]->before[0] = NULL;
233 case Undo_CreateWaypoint:
234 case Undo_MoveWaypoint:
235 case Undo_AppendWaypoint:
241 undoStack.erase(undoStack.begin(), undoStack.begin() + stackpointer);
245 void Undo::InvalidateUndo() {
250 bool Undo::UndoLastAction() {
251 if (!AnythingToUndo())
return false;
254 switch (action->type) {
255 case Undo_CreateWaypoint:
256 doRedoDeleteWaypoint(action,
261 case Undo_MoveWaypoint:
262 doUndoMoveWaypoint(action, GetParent());
266 case Undo_DeleteWaypoint:
267 doUndoDeleteWaypoint(action, GetParent());
271 case Undo_AppendWaypoint:
273 doUndoAppendWaypoint(action, GetParent());
279 bool Undo::RedoNextAction() {
280 if (!AnythingToRedo())
return false;
283 switch (action->type) {
284 case Undo_CreateWaypoint:
285 doUndoDeleteWaypoint(action,
290 case Undo_MoveWaypoint:
297 case Undo_DeleteWaypoint:
298 doRedoDeleteWaypoint(action, GetParent());
302 case Undo_AppendWaypoint:
303 doRedoAppendWaypoint(action, GetParent());
310 bool Undo::BeforeUndoableAction(UndoType type, UndoItemPointer before,
311 UndoBeforePointerType beforeType,
312 UndoItemPointer selectable) {
313 if (CancelUndoableAction())
return false;
318 candidate->before.clear();
319 candidate->beforeType.clear();
320 candidate->selectable.clear();
321 candidate->after.clear();
323 candidate->type = type;
324 UndoItemPointer subject = before;
326 switch (beforeType) {
327 case Undo_NeedsCopy: {
328 switch (candidate->type) {
329 case Undo_MoveWaypoint: {
330 wxRealPoint* point =
new wxRealPoint;
332 point->x = rp->m_lon;
333 point->y = rp->m_lat;
337 case Undo_CreateWaypoint:
339 case Undo_DeleteWaypoint:
341 case Undo_AppendWaypoint:
346 case Undo_IsOrphanded:
352 candidate->before.push_back(subject);
353 candidate->beforeType.push_back(beforeType);
354 candidate->selectable.push_back(selectable);
356 isInsideUndoableAction =
true;
360 bool Undo::AfterUndoableAction(UndoItemPointer after) {
361 if (!isInsideUndoableAction)
return false;
363 candidate->after.push_back(after);
364 undoStack.push_front(candidate);
366 if (undoStack.size() > depthSetting) {
367 undoStack.pop_back();
370 isInsideUndoableAction =
false;
374 bool Undo::CancelUndoableAction(
bool noDataDelete) {
375 if (isInsideUndoableAction) {
377 for (
unsigned int i = 0; i < candidate->beforeType.size(); i++) {
378 if (candidate->beforeType[i] == Undo_IsOrphanded) {
379 candidate->beforeType[i] = Undo_HasParent;
383 if (candidate)
delete candidate;
385 isInsideUndoableAction =
false;
393 UndoAction::~UndoAction() {
394 assert(before.size() == beforeType.size());
396 for (
unsigned int i = 0; i < before.size(); i++) {
397 switch (beforeType[i]) {
398 case Undo_NeedsCopy: {
400 case Undo_MoveWaypoint:
402 delete (wxRealPoint*)before[i];
406 case Undo_DeleteWaypoint:
408 case Undo_CreateWaypoint:
410 case Undo_AppendWaypoint:
415 case Undo_IsOrphanded: {
417 case Undo_DeleteWaypoint:
422 case Undo_CreateWaypoint:
424 case Undo_MoveWaypoint:
426 case Undo_AppendWaypoint: