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"
64 isInsideUndoableAction =
false;
69 for (
unsigned int i = 0; i < undoStack.size(); i++) {
78wxString UndoAction::Description() {
81 case Undo_CreateWaypoint:
82 descr = _(
"Create Mark");
84 case Undo_DeleteWaypoint:
85 descr = _(
"Delete Mark");
87 case Undo_MoveWaypoint:
88 descr = _(
"Move Waypoint");
90 case Undo_AppendWaypoint:
91 descr = _(
"Append Waypoint");
103 wxRealPoint* lastPoint = (wxRealPoint*)action->before[0];
104 lat = currentPoint->m_lat;
105 lon = currentPoint->m_lon;
106 currentPoint->m_lat = lastPoint->y;
107 currentPoint->m_lon = lastPoint->x;
111 selectable->m_slat = currentPoint->m_lat;
112 selectable->m_slon = currentPoint->m_lon;
114 if ((NULL != g_pMarkInfoDialog) && (g_pMarkInfoDialog->IsShown())) {
115 if (currentPoint == g_pMarkInfoDialog->GetRoutePoint())
116 g_pMarkInfoDialog->UpdateProperties(
true);
119 wxArrayPtrVoid* routeArray =
122 for (
unsigned int ir = 0; ir < routeArray->GetCount(); ir++) {
124 pr->FinalizeForRendering();
125 pr->UpdateSegmentDistances();
126 NavObj_dB::GetInstance().UpdateRoute(pr);
134 pSelect->AddSelectableRoutePoint(point->m_lat, point->m_lon, point);
135 NavObj_dB::GetInstance().InsertRoutePoint(point);
139 if (NULL != pWayPointMan) pWayPointMan->
AddRoutePoint(point);
140 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
141 pRouteManagerDialog->UpdateWptListCtrl();
146 NavObj_dB::GetInstance().DeleteRoutePoint(point);
147 pSelect->DeleteSelectablePoint(point, SELTYPE_ROUTEPOINT);
149 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
150 pRouteManagerDialog->UpdateWptListCtrl();
157 bool noRouteLeftToRedo =
false;
158 if ((route->GetnPoints() == 2) && (cc->m_routeState == 0))
159 noRouteLeftToRedo =
true;
161 g_pRouteMan->RemovePointFromRoute(point, route, cc->m_routeState);
162 gFrame->InvalidateAllGL();
164 if (action->beforeType[0] == Undo_IsOrphanded) {
165 NavObj_dB::GetInstance().DeleteRoutePoint(point);
166 pSelect->DeleteSelectablePoint(point, SELTYPE_ROUTEPOINT);
170 if (noRouteLeftToRedo) {
171 cc->undo->InvalidateRedo();
174 if (RouteManagerDialog::getInstanceFlag()) {
175 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
176 pRouteManagerDialog->UpdateWptListCtrl();
179 if (cc->m_routeState > 1) {
181 cc->m_prev_pMousePoint = route->GetLastPoint();
182 cc->m_prev_rlat = cc->m_prev_pMousePoint->m_lat;
183 cc->m_prev_rlon = cc->m_prev_pMousePoint->m_lon;
184 route->m_lastMousePointIndex = route->GetnPoints();
192 if (action->beforeType[0] == Undo_IsOrphanded) {
193 NavObj_dB::GetInstance().InsertRoutePoint(point);
194 pSelect->AddSelectableRoutePoint(point->m_lat, point->m_lon, point);
197 RoutePoint* prevpoint = route->GetLastPoint();
199 route->AddPoint(point);
200 pSelect->AddSelectableRouteSegment(prevpoint->m_lat, prevpoint->m_lon,
201 point->m_lat, point->m_lon, prevpoint,
204 if (pRouteManagerDialog && pRouteManagerDialog->IsShown())
205 pRouteManagerDialog->UpdateWptListCtrl();
207 if (cc->m_routeState > 1) {
209 cc->m_prev_pMousePoint = route->GetLastPoint();
210 cc->m_prev_rlat = cc->m_prev_pMousePoint->m_lat;
211 cc->m_prev_rlon = cc->m_prev_pMousePoint->m_lon;
212 route->m_lastMousePointIndex = route->GetnPoints();
216bool Undo::AnythingToUndo() {
return undoStack.size() > stackpointer; }
218bool Undo::AnythingToRedo() {
return stackpointer > 0; }
220UndoAction* Undo::GetNextUndoableAction() {
return undoStack[stackpointer]; }
223 return undoStack[stackpointer - 1];
226void Undo::InvalidateRedo() {
227 if (stackpointer == 0)
return;
232 for (
unsigned int i = 0; i < stackpointer; i++) {
233 switch (undoStack[i]->type) {
234 case Undo_DeleteWaypoint:
235 undoStack[i]->before[0] = NULL;
237 case Undo_CreateWaypoint:
238 case Undo_MoveWaypoint:
239 case Undo_AppendWaypoint:
245 undoStack.erase(undoStack.begin(), undoStack.begin() + stackpointer);
249void Undo::InvalidateUndo() {
254bool Undo::UndoLastAction() {
255 if (!AnythingToUndo())
return false;
258 switch (action->type) {
259 case Undo_CreateWaypoint:
260 doRedoDeleteWaypoint(action,
265 case Undo_MoveWaypoint:
266 doUndoMoveWaypoint(action, GetParent());
270 case Undo_DeleteWaypoint:
271 doUndoDeleteWaypoint(action, GetParent());
275 case Undo_AppendWaypoint:
277 doUndoAppendWaypoint(action, GetParent());
283bool Undo::RedoNextAction() {
284 if (!AnythingToRedo())
return false;
287 switch (action->type) {
288 case Undo_CreateWaypoint:
289 doUndoDeleteWaypoint(action,
294 case Undo_MoveWaypoint:
301 case Undo_DeleteWaypoint:
302 doRedoDeleteWaypoint(action, GetParent());
306 case Undo_AppendWaypoint:
307 doRedoAppendWaypoint(action, GetParent());
314bool Undo::BeforeUndoableAction(UndoType type, UndoItemPointer before,
315 UndoBeforePointerType beforeType,
316 UndoItemPointer selectable) {
317 if (CancelUndoableAction())
return false;
322 candidate->before.clear();
323 candidate->beforeType.clear();
324 candidate->selectable.clear();
325 candidate->after.clear();
327 candidate->type = type;
328 UndoItemPointer subject = before;
330 switch (beforeType) {
331 case Undo_NeedsCopy: {
332 switch (candidate->type) {
333 case Undo_MoveWaypoint: {
334 wxRealPoint* point =
new wxRealPoint;
336 point->x = rp->m_lon;
337 point->y = rp->m_lat;
341 case Undo_CreateWaypoint:
343 case Undo_DeleteWaypoint:
345 case Undo_AppendWaypoint:
350 case Undo_IsOrphanded:
356 candidate->before.push_back(subject);
357 candidate->beforeType.push_back(beforeType);
358 candidate->selectable.push_back(selectable);
360 isInsideUndoableAction =
true;
364bool Undo::AfterUndoableAction(UndoItemPointer after) {
365 if (!isInsideUndoableAction)
return false;
367 candidate->after.push_back(after);
368 undoStack.push_front(candidate);
370 if (undoStack.size() > depthSetting) {
371 undoStack.pop_back();
374 isInsideUndoableAction =
false;
378bool Undo::CancelUndoableAction(
bool noDataDelete) {
379 if (isInsideUndoableAction) {
381 for (
unsigned int i = 0; i < candidate->beforeType.size(); i++) {
382 if (candidate->beforeType[i] == Undo_IsOrphanded) {
383 candidate->beforeType[i] = Undo_HasParent;
387 if (candidate)
delete candidate;
389 isInsideUndoableAction =
false;
397UndoAction::~UndoAction() {
398 assert(before.size() == beforeType.size());
400 for (
unsigned int i = 0; i < before.size(); i++) {
401 switch (beforeType[i]) {
402 case Undo_NeedsCopy: {
404 case Undo_MoveWaypoint:
406 delete (wxRealPoint*)before[i];
410 case Undo_DeleteWaypoint:
412 case Undo_CreateWaypoint:
414 case Undo_AppendWaypoint:
419 case Undo_IsOrphanded: {
421 case Undo_DeleteWaypoint:
426 case Undo_CreateWaypoint:
428 case Undo_MoveWaypoint:
430 case Undo_AppendWaypoint:
ChartCanvas - Main chart display and interaction component.
Dialog for displaying and editing waypoint properties.
Represents a waypoint or mark within the navigation system.
Represents a navigational route in the navigation system.
wxArrayPtrVoid * GetRouteArrayContaining(RoutePoint *pWP)
Find all routes that contain the given waypoint.
bool AddRoutePoint(RoutePoint *prp)
Add a point to list which owns it.
bool RemoveRoutePoint(RoutePoint *prp)
Remove a routepoint from list if present, deallocate it all cases.