Path: blob/main/src/netedit/dialogs/GNEUndoListDialog.cpp
169678 views
/****************************************************************************/1// Eclipse SUMO, Simulation of Urban MObility; see https://eclipse.dev/sumo2// Copyright (C) 2001-2025 German Aerospace Center (DLR) and others.3// This program and the accompanying materials are made available under the4// terms of the Eclipse Public License 2.0 which is available at5// https://www.eclipse.org/legal/epl-2.0/6// This Source Code may also be made available under the following Secondary7// Licenses when the conditions for such availability set forth in the Eclipse8// Public License 2.0 are satisfied: GNU General Public License, version 29// or later which is available at10// https://www.gnu.org/licenses/old-licenses/gpl-2.0-standalone.html11// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-or-later12/****************************************************************************/13/// @file GNEUndoListDialog.cpp14/// @author Pablo Alvarez Lopez15/// @date Oct 202116///17// Dialog for show undo-list18/****************************************************************************/1920#include <netedit/GNEApplicationWindow.h>21#include <netedit/GNEUndoList.h>22#include <utils/gui/div/GUIDesigns.h>23#include <utils/foxtools/MFXTextFieldIcon.h>2425#include "GNEUndoListDialog.h"2627// ===========================================================================28// FOX callback mapping29// ===========================================================================3031FXDEFMAP(GNEUndoListDialog) GNEUndoListDialogMap[] = {32FXMAPFUNC(SEL_COMMAND, MID_CHOOSEN_OPERATION, GNEUndoListDialog::onCmdSelectRow),33};3435// Object implementation36FXIMPLEMENT(GNEUndoListDialog, GNEDialog, GNEUndoListDialogMap, ARRAYNUMBER(GNEUndoListDialogMap))3738// ===========================================================================39// member method definitions40// ===========================================================================4142GNEUndoListDialog::GNEUndoListDialog(GNEApplicationWindow* applicationWindow) :43GNEDialog(applicationWindow, TL("Undo/Redo history"), GUIIcon::UNDOLIST,44DialogType::UNDOLIST, Buttons::OK, OpenType::MODAL, ResizeMode::STATIC) {45// create scroll windows for rows46auto* scrollWindowsContents = new FXScrollWindow(myContentFrame, GUIDesignScrollWindowFixed(560, 400));47myRowFrame = new FXVerticalFrame(scrollWindowsContents, GUIDesignAuxiliarFrame);48// set background clor49myRowFrame->setBackColor(GUIDesignBackgroundColorWhite);50// declare redo iterator over undoList and fill rows51GNEUndoList::RedoIterator itRedo(myApplicationWindow->getUndoList());52while (!itRedo.end()) {53myGUIRows.push_back(new GUIRow(this, myRowFrame, myApplicationWindow->getStaticTooltipView()));54itRedo++;55}56// declare undo iterator over undoList and fill rows57GNEUndoList::UndoIterator itUndo(myApplicationWindow->getUndoList());58while (!itUndo.end()) {59myGUIRows.push_back(new GUIRow(this, myRowFrame, myApplicationWindow->getStaticTooltipView()));60itUndo++;61}62// update list63updateList();64// open dialog65openDialog();66}676869GNEUndoListDialog::~GNEUndoListDialog() {}707172void73GNEUndoListDialog::runInternalTest(const InternalTestStep::DialogArgument* /*dialogArgument*/) {74// nothing to do75}767778long79GNEUndoListDialog::onCmdSelectRow(FXObject* obj, FXSelector, void*) {80int index = 0;81// search button82for (const auto& row : myGUIRows) {83if (row->getRadioButton() == obj) {84index = row->getIndex();85}86}87// now apply undo-redos88if (index < 0) {89for (int i = 0; i < (index * -1); i++) {90myApplicationWindow->getUndoList()->undo();91}92} else {93for (int i = 0; i < index; i++) {94myApplicationWindow->getUndoList()->redo();95}96}97// update list again98updateList();99return 1;100}101102103void104GNEUndoListDialog::updateList() {105// declare vector of undoListRows106std::vector<UndoListRow> undoListRows;107// declare redo iterator over UndoList108GNEUndoList::RedoIterator itRedo(myApplicationWindow->getUndoList());109// declare index110int index = 1;111// fill undoListRows rows with elements to redo (in inverse)112while (!itRedo.end()) {113undoListRows.push_back(UndoListRow(index, itRedo.getIcon(), itRedo.getDescription(), itRedo.getTimeStamp()));114// update counters115itRedo++;116index++;117}118// reverse undoListRows rows (because redo are inserted inverted)119std::reverse(undoListRows.begin(), undoListRows.end());120// declare undo iterator over UndoList121GNEUndoList::UndoIterator itUndo(myApplicationWindow->getUndoList());122// reset index123index = 0;124// fill undoListRows with elements to undo125while (!itUndo.end()) {126undoListRows.push_back(UndoListRow(index, itUndo.getIcon(), itUndo.getDescription(), itUndo.getTimeStamp()));127// update counters128itUndo++;129index--;130}131// fill GUIRows with undoListRows132for (int i = 0; i < (int)undoListRows.size(); i++) {133myGUIRows.at(i)->update(undoListRows.at(i));134if (undoListRows.at(i).index < 0) {135myGUIRows.at(i)->setBlueBackground();136} else if (undoListRows.at(i).index > 0) {137myGUIRows.at(i)->setRedBackground();138} else {139myGUIRows.at(i)->checkRow();140}141}142}143144145GNEUndoListDialog::UndoListRow::UndoListRow(const int index_, FXIcon* icon_, const std::string description_, const std::string timestamp_) :146index(index_),147icon(icon_),148description(description_),149timestamp(timestamp_) {}150151152GNEUndoListDialog::GUIRow::GUIRow(GNEUndoListDialog* undoListDialog, FXVerticalFrame* mainFrame, MFXStaticToolTip* staticToolTip) {153FXHorizontalFrame* horizontalFrame = new FXHorizontalFrame(mainFrame, GUIDesignAuxiliarHorizontalFrame);154// build radio button155myRadioButton = new FXRadioButton(horizontalFrame, "", undoListDialog, MID_CHOOSEN_OPERATION, GUIDesignRadioButtonSquared);156// build icon label157myIcon = new FXLabel(horizontalFrame, "", nullptr, GUIDesignLabelIconThick);158// build description label159myTextFieldDescription = new MFXTextFieldIcon(horizontalFrame, staticToolTip, GUIIcon::EMPTY, undoListDialog, MID_GNE_SET_ATTRIBUTE, GUIDesignTextField);160myTextFieldDescription->setEditable(false);161// build text label162myTextFieldTimeStamp = new FXTextField(horizontalFrame, GUIDesignTextFieldNCol, undoListDialog, MID_GNE_SET_ATTRIBUTE, GUIDesignTextFieldFixed(70));163myTextFieldTimeStamp->setEditable(false);164}165166167GNEUndoListDialog::GUIRow::~GUIRow() {168delete myRadioButton;169delete myIcon;170delete myTextFieldDescription;171delete myTextFieldTimeStamp;172}173174175void176GNEUndoListDialog::GUIRow::update(const UndoListRow& row) {177myIndex = row.index;178myIcon->setIcon(row.icon);179// check if text must be trimmed180if (row.description.size() > 57) {181std::string textFieldTrimmed;182for (int i = 0; i < 57; i++) {183textFieldTrimmed.push_back(row.description.at(i));184}185textFieldTrimmed.append("...");186myTextFieldDescription->setText(textFieldTrimmed.c_str());187myTextFieldDescription->setToolTipText(row.description.c_str());188} else {189myTextFieldDescription->setText(row.description.c_str());190myTextFieldDescription->setToolTipText("");191}192myTextFieldTimeStamp->setText(row.timestamp.c_str());193}194195196int197GNEUndoListDialog::GUIRow::getIndex() const {198return myIndex;199}200201202const FXRadioButton*203GNEUndoListDialog::GUIRow::getRadioButton() const {204return myRadioButton;205}206207208void209GNEUndoListDialog::GUIRow::setRedBackground() {210myRadioButton->setCheck(FALSE);211myRadioButton->setBackColor(GUIDesignBackgroundColorRed);212}213214215void216GNEUndoListDialog::GUIRow::setBlueBackground() {217myRadioButton->setCheck(FALSE);218myRadioButton->setBackColor(FXRGBA(210, 233, 255, 255));219}220221222void223GNEUndoListDialog::GUIRow::checkRow() {224myRadioButton->setCheck(TRUE);225myRadioButton->setBackColor(FXRGBA(240, 255, 205, 255));226}227228229