Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
eclipse
GitHub Repository: eclipse/sumo
Path: blob/main/src/netedit/dialogs/GNEUndoListDialog.cpp
169678 views
1
/****************************************************************************/
2
// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo
3
// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.
4
// This program and the accompanying materials are made available under the
5
// terms of the Eclipse Public License 2.0 which is available at
6
// https://www.eclipse.org/legal/epl-2.0/
7
// This Source Code may also be made available under the following Secondary
8
// Licenses when the conditions for such availability set forth in the Eclipse
9
// Public License 2.0 are satisfied: GNU General Public License, version 2
10
// or later which is available at
11
// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html
12
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later
13
/****************************************************************************/
14
/// @file GNEUndoListDialog.cpp
15
/// @author Pablo Alvarez Lopez
16
/// @date Oct 2021
17
///
18
// Dialog for show undo-list
19
/****************************************************************************/
20
21
#include <netedit/GNEApplicationWindow.h>
22
#include <netedit/GNEUndoList.h>
23
#include <utils/gui/div/GUIDesigns.h>
24
#include <utils/foxtools/MFXTextFieldIcon.h>
25
26
#include "GNEUndoListDialog.h"
27
28
// ===========================================================================
29
// FOX callback mapping
30
// ===========================================================================
31
32
FXDEFMAP(GNEUndoListDialog) GNEUndoListDialogMap[] = {
33
FXMAPFUNC(SEL_COMMAND, MID_CHOOSEN_OPERATION, GNEUndoListDialog::onCmdSelectRow),
34
};
35
36
// Object implementation
37
FXIMPLEMENT(GNEUndoListDialog, GNEDialog, GNEUndoListDialogMap, ARRAYNUMBER(GNEUndoListDialogMap))
38
39
// ===========================================================================
40
// member method definitions
41
// ===========================================================================
42
43
GNEUndoListDialog::GNEUndoListDialog(GNEApplicationWindow* applicationWindow) :
44
GNEDialog(applicationWindow, TL("Undo/Redo history"), GUIIcon::UNDOLIST,
45
DialogType::UNDOLIST, Buttons::OK, OpenType::MODAL, ResizeMode::STATIC) {
46
// create scroll windows for rows
47
auto* scrollWindowsContents = new FXScrollWindow(myContentFrame, GUIDesignScrollWindowFixed(560, 400));
48
myRowFrame = new FXVerticalFrame(scrollWindowsContents, GUIDesignAuxiliarFrame);
49
// set background clor
50
myRowFrame->setBackColor(GUIDesignBackgroundColorWhite);
51
// declare redo iterator over undoList and fill rows
52
GNEUndoList::RedoIterator itRedo(myApplicationWindow->getUndoList());
53
while (!itRedo.end()) {
54
myGUIRows.push_back(new GUIRow(this, myRowFrame, myApplicationWindow->getStaticTooltipView()));
55
itRedo++;
56
}
57
// declare undo iterator over undoList and fill rows
58
GNEUndoList::UndoIterator itUndo(myApplicationWindow->getUndoList());
59
while (!itUndo.end()) {
60
myGUIRows.push_back(new GUIRow(this, myRowFrame, myApplicationWindow->getStaticTooltipView()));
61
itUndo++;
62
}
63
// update list
64
updateList();
65
// open dialog
66
openDialog();
67
}
68
69
70
GNEUndoListDialog::~GNEUndoListDialog() {}
71
72
73
void
74
GNEUndoListDialog::runInternalTest(const InternalTestStep::DialogArgument* /*dialogArgument*/) {
75
// nothing to do
76
}
77
78
79
long
80
GNEUndoListDialog::onCmdSelectRow(FXObject* obj, FXSelector, void*) {
81
int index = 0;
82
// search button
83
for (const auto& row : myGUIRows) {
84
if (row->getRadioButton() == obj) {
85
index = row->getIndex();
86
}
87
}
88
// now apply undo-redos
89
if (index < 0) {
90
for (int i = 0; i < (index * -1); i++) {
91
myApplicationWindow->getUndoList()->undo();
92
}
93
} else {
94
for (int i = 0; i < index; i++) {
95
myApplicationWindow->getUndoList()->redo();
96
}
97
}
98
// update list again
99
updateList();
100
return 1;
101
}
102
103
104
void
105
GNEUndoListDialog::updateList() {
106
// declare vector of undoListRows
107
std::vector<UndoListRow> undoListRows;
108
// declare redo iterator over UndoList
109
GNEUndoList::RedoIterator itRedo(myApplicationWindow->getUndoList());
110
// declare index
111
int index = 1;
112
// fill undoListRows rows with elements to redo (in inverse)
113
while (!itRedo.end()) {
114
undoListRows.push_back(UndoListRow(index, itRedo.getIcon(), itRedo.getDescription(), itRedo.getTimeStamp()));
115
// update counters
116
itRedo++;
117
index++;
118
}
119
// reverse undoListRows rows (because redo are inserted inverted)
120
std::reverse(undoListRows.begin(), undoListRows.end());
121
// declare undo iterator over UndoList
122
GNEUndoList::UndoIterator itUndo(myApplicationWindow->getUndoList());
123
// reset index
124
index = 0;
125
// fill undoListRows with elements to undo
126
while (!itUndo.end()) {
127
undoListRows.push_back(UndoListRow(index, itUndo.getIcon(), itUndo.getDescription(), itUndo.getTimeStamp()));
128
// update counters
129
itUndo++;
130
index--;
131
}
132
// fill GUIRows with undoListRows
133
for (int i = 0; i < (int)undoListRows.size(); i++) {
134
myGUIRows.at(i)->update(undoListRows.at(i));
135
if (undoListRows.at(i).index < 0) {
136
myGUIRows.at(i)->setBlueBackground();
137
} else if (undoListRows.at(i).index > 0) {
138
myGUIRows.at(i)->setRedBackground();
139
} else {
140
myGUIRows.at(i)->checkRow();
141
}
142
}
143
}
144
145
146
GNEUndoListDialog::UndoListRow::UndoListRow(const int index_, FXIcon* icon_, const std::string description_, const std::string timestamp_) :
147
index(index_),
148
icon(icon_),
149
description(description_),
150
timestamp(timestamp_) {}
151
152
153
GNEUndoListDialog::GUIRow::GUIRow(GNEUndoListDialog* undoListDialog, FXVerticalFrame* mainFrame, MFXStaticToolTip* staticToolTip) {
154
FXHorizontalFrame* horizontalFrame = new FXHorizontalFrame(mainFrame, GUIDesignAuxiliarHorizontalFrame);
155
// build radio button
156
myRadioButton = new FXRadioButton(horizontalFrame, "", undoListDialog, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonSquared);
157
// build icon label
158
myIcon = new FXLabel(horizontalFrame, "", nullptr, GUIDesignLabelIconThick);
159
// build description label
160
myTextFieldDescription = new MFXTextFieldIcon(horizontalFrame, staticToolTip, GUIIcon::EMPTY, undoListDialog, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);
161
myTextFieldDescription->setEditable(false);
162
// build text label
163
myTextFieldTimeStamp = new FXTextField(horizontalFrame, GUIDesignTextFieldNCol, undoListDialog, MID_GNE_SET_ATTRIBUTE, GUIDesignTextFieldFixed(70));
164
myTextFieldTimeStamp->setEditable(false);
165
}
166
167
168
GNEUndoListDialog::GUIRow::~GUIRow() {
169
delete myRadioButton;
170
delete myIcon;
171
delete myTextFieldDescription;
172
delete myTextFieldTimeStamp;
173
}
174
175
176
void
177
GNEUndoListDialog::GUIRow::update(const UndoListRow& row) {
178
myIndex = row.index;
179
myIcon->setIcon(row.icon);
180
// check if text must be trimmed
181
if (row.description.size() > 57) {
182
std::string textFieldTrimmed;
183
for (int i = 0; i < 57; i++) {
184
textFieldTrimmed.push_back(row.description.at(i));
185
}
186
textFieldTrimmed.append("...");
187
myTextFieldDescription->setText(textFieldTrimmed.c_str());
188
myTextFieldDescription->setToolTipText(row.description.c_str());
189
} else {
190
myTextFieldDescription->setText(row.description.c_str());
191
myTextFieldDescription->setToolTipText("");
192
}
193
myTextFieldTimeStamp->setText(row.timestamp.c_str());
194
}
195
196
197
int
198
GNEUndoListDialog::GUIRow::getIndex() const {
199
return myIndex;
200
}
201
202
203
const FXRadioButton*
204
GNEUndoListDialog::GUIRow::getRadioButton() const {
205
return myRadioButton;
206
}
207
208
209
void
210
GNEUndoListDialog::GUIRow::setRedBackground() {
211
myRadioButton->setCheck(FALSE);
212
myRadioButton->setBackColor(GUIDesignBackgroundColorRed);
213
}
214
215
216
void
217
GNEUndoListDialog::GUIRow::setBlueBackground() {
218
myRadioButton->setCheck(FALSE);
219
myRadioButton->setBackColor(FXRGBA(210, 233, 255, 255));
220
}
221
222
223
void
224
GNEUndoListDialog::GUIRow::checkRow() {
225
myRadioButton->setCheck(TRUE);
226
myRadioButton->setBackColor(FXRGBA(240, 255, 205, 255));
227
}
228
229