From c155354de1ae6138d28cc455a37c6ac9f0750e3b 2017-07-04 07:43:57 From: Alexandre Leroux Date: 2017-07-04 07:43:57 Subject: [PATCH] Merge branch 'feature/VariableDeletion' into develop --- diff --git a/app/src/MainWindow.cpp b/app/src/MainWindow.cpp index 6fbd08b..05951cb 100644 --- a/app/src/MainWindow.cpp +++ b/app/src/MainWindow.cpp @@ -173,6 +173,10 @@ MainWindow::MainWindow(QWidget *parent) auto timeWidget = new TimeWidget{}; mainToolBar->addWidget(timeWidget); + // Controllers / controllers connections + connect(&sqpApp->timeController(), SIGNAL(timeUpdated(SqpDateTime)), + &sqpApp->variableController(), SLOT(onDateTimeOnSelection(SqpDateTime))); + // Widgets / controllers connections // DataSource @@ -183,8 +187,10 @@ MainWindow::MainWindow(QWidget *parent) connect(timeWidget, SIGNAL(timeUpdated(SqpDateTime)), &sqpApp->timeController(), SLOT(onTimeToUpdate(SqpDateTime))); - connect(&sqpApp->timeController(), SIGNAL(timeUpdated(SqpDateTime)), - &sqpApp->variableController(), SLOT(onDateTimeOnSelection(SqpDateTime))); + // Visualization + connect(&sqpApp->visualizationController(), + SIGNAL(variableAboutToBeDeleted(std::shared_ptr)), m_Ui->view, + SLOT(onVariableAboutToBeDeleted(std::shared_ptr))); // Widgets / widgets connections diff --git a/core/include/Variable/VariableCacheController.h b/core/include/Variable/VariableCacheController.h index 57ef371..7830d0a 100644 --- a/core/include/Variable/VariableCacheController.h +++ b/core/include/Variable/VariableCacheController.h @@ -1,6 +1,7 @@ #ifndef SCIQLOP_VARIABLECACHECONTROLLER_H #define SCIQLOP_VARIABLECACHECONTROLLER_H +#include #include #include @@ -9,6 +10,8 @@ #include +Q_DECLARE_LOGGING_CATEGORY(LOG_VariableCacheController) + class Variable; Q_DECLARE_LOGGING_CATEGORY(LOG_VariableCacheController) @@ -23,6 +26,9 @@ public: void addDateTime(std::shared_ptr variable, const SqpDateTime &dateTime); + /// Clears cache concerning a variable + void clear(std::shared_ptr variable) noexcept; + /// Return all of the SqpDataTime part of the dateTime whose are not in the cache QVector provideNotInCacheDateTimeList(std::shared_ptr variable, const SqpDateTime &dateTime); diff --git a/core/include/Variable/VariableController.h b/core/include/Variable/VariableController.h index 02bc847..f7bcf49 100644 --- a/core/include/Variable/VariableController.h +++ b/core/include/Variable/VariableController.h @@ -30,8 +30,29 @@ public: void setTimeController(TimeController *timeController) noexcept; + /** + * Deletes from the controller the variable passed in parameter. + * + * Delete a variable includes: + * - the deletion of the various references to the variable in SciQlop + * - the deletion of the model variable + * - the deletion of the provider associated with the variable + * - removing the cache associated with the variable + * + * @param variable the variable to delete from the controller. + */ + void deleteVariable(std::shared_ptr variable) noexcept; + + /** + * Deletes from the controller the variables passed in parameter. + * @param variables the variables to delete from the controller. + * @sa deleteVariable() + */ + void deleteVariables(const QVector > &variables) noexcept; signals: + /// Signal emitted when a variable is about to be deleted from the controller + void variableAboutToBeDeleted(std::shared_ptr variable); /// Signal emitted when a variable has been created void variableCreated(std::shared_ptr variable); diff --git a/core/include/Variable/VariableModel.h b/core/include/Variable/VariableModel.h index 7fa865a..9e78a94 100644 --- a/core/include/Variable/VariableModel.h +++ b/core/include/Variable/VariableModel.h @@ -30,6 +30,12 @@ public: std::shared_ptr createVariable(const QString &name, const SqpDateTime &dateTime) noexcept; + /** + * Deletes a variable from the model, if it exists + * @param variable the variable to delete + */ + void deleteVariable(std::shared_ptr variable) noexcept; + std::shared_ptr variable(int index) const; // /////////////////////////// // diff --git a/core/include/Visualization/VisualizationController.h b/core/include/Visualization/VisualizationController.h index 9664fe6..97937e6 100644 --- a/core/include/Visualization/VisualizationController.h +++ b/core/include/Visualization/VisualizationController.h @@ -26,6 +26,8 @@ public: virtual ~VisualizationController(); signals: + /// Signal emitted when a variable is about to be deleted from SciQlop + void variableAboutToBeDeleted(std::shared_ptr variable); /// Signal emitted when a variable has been created in SciQlop void variableCreated(std::shared_ptr variable); diff --git a/core/src/Variable/VariableCacheController.cpp b/core/src/Variable/VariableCacheController.cpp index a648b4d..7c42f2d 100644 --- a/core/src/Variable/VariableCacheController.cpp +++ b/core/src/Variable/VariableCacheController.cpp @@ -61,6 +61,22 @@ void VariableCacheController::addDateTime(std::shared_ptr variable, } } +void VariableCacheController::clear(std::shared_ptr variable) noexcept +{ + if (!variable) { + qCCritical(LOG_VariableCacheController()) << "Can't clear variable cache: variable is null"; + return; + } + + auto nbEntries = impl->m_VariableToSqpDateTimeListMap.erase(variable); + + auto clearCacheMessage + = (nbEntries != 0) + ? tr("Variable cache cleared for variable %1").arg(variable->name()) + : tr("No deletion of variable cache: no cache was associated with the variable"); + qCDebug(LOG_VariableCacheController()) << clearCacheMessage; +} + QVector VariableCacheController::provideNotInCacheDateTimeList(std::shared_ptr variable, const SqpDateTime &dateTime) diff --git a/core/src/Variable/VariableController.cpp b/core/src/Variable/VariableController.cpp index 0ac0a8b..c0c8034 100644 --- a/core/src/Variable/VariableController.cpp +++ b/core/src/Variable/VariableController.cpp @@ -82,6 +82,38 @@ void VariableController::setTimeController(TimeController *timeController) noexc impl->m_TimeController = timeController; } +void VariableController::deleteVariable(std::shared_ptr variable) noexcept +{ + if (!variable) { + qCCritical(LOG_VariableController()) << "Can't delete variable: variable is null"; + return; + } + + // Spreads in SciQlop that the variable will be deleted, so that potential receivers can + // make some treatments before the deletion + emit variableAboutToBeDeleted(variable); + + // Deletes provider + auto nbProvidersDeleted = impl->m_VariableToProviderMap.erase(variable); + qCDebug(LOG_VariableController()) + << tr("Number of providers deleted for variable %1: %2") + .arg(variable->name(), QString::number(nbProvidersDeleted)); + + // Clears cache + impl->m_VariableCacheController->clear(variable); + + // Deletes from model + impl->m_VariableModel->deleteVariable(variable); +} + +void VariableController::deleteVariables( + const QVector > &variables) noexcept +{ + for (auto variable : qAsConst(variables)) { + deleteVariable(variable); + } +} + void VariableController::createVariable(const QString &name, std::shared_ptr provider) noexcept { diff --git a/core/src/Variable/VariableModel.cpp b/core/src/Variable/VariableModel.cpp index 9d6c6f1..b8510dc 100644 --- a/core/src/Variable/VariableModel.cpp +++ b/core/src/Variable/VariableModel.cpp @@ -69,6 +69,32 @@ std::shared_ptr VariableModel::createVariable(const QString &name, return variable; } +void VariableModel::deleteVariable(std::shared_ptr variable) noexcept +{ + if (!variable) { + qCCritical(LOG_Variable()) << "Can't delete a null variable from the model"; + return; + } + + // Finds variable in the model + auto begin = impl->m_Variables.cbegin(); + auto end = impl->m_Variables.cend(); + auto it = std::find(begin, end, variable); + if (it != end) { + auto removeIndex = std::distance(begin, it); + + // Deletes variable + beginRemoveRows({}, removeIndex, removeIndex); + impl->m_Variables.erase(it); + endRemoveRows(); + } + else { + qCritical(LOG_VariableModel()) + << tr("Can't delete variable %1 from the model: the variable is not in the model") + .arg(variable->name()); + } +} + std::shared_ptr VariableModel::variable(int index) const { return (index >= 0 && index < impl->m_Variables.size()) ? impl->m_Variables[index] : nullptr; diff --git a/gui/include/Visualization/IVariableContainer.h b/gui/include/Visualization/IVariableContainer.h index fa4791b..ac49faa 100644 --- a/gui/include/Visualization/IVariableContainer.h +++ b/gui/include/Visualization/IVariableContainer.h @@ -13,6 +13,9 @@ public: /// Checks if the container can handle the variable passed in parameter virtual bool canDrop(const Variable &variable) const = 0; + + /// Checks if the container contains the variable passed in parameter + virtual bool contains(const Variable &variable) const = 0; }; diff --git a/gui/include/Visualization/VisualizationGraphWidget.h b/gui/include/Visualization/VisualizationGraphWidget.h index 28673a8..ef0e800 100644 --- a/gui/include/Visualization/VisualizationGraphWidget.h +++ b/gui/include/Visualization/VisualizationGraphWidget.h @@ -35,6 +35,7 @@ public: // IVisualizationWidget interface void accept(IVisualizationWidgetVisitor *visitor) override; bool canDrop(const Variable &variable) const override; + bool contains(const Variable &variable) const override; QString name() const override; void updateDisplay(std::shared_ptr variable); diff --git a/gui/include/Visualization/VisualizationTabWidget.h b/gui/include/Visualization/VisualizationTabWidget.h index d4816ef..ca9b4c8 100644 --- a/gui/include/Visualization/VisualizationTabWidget.h +++ b/gui/include/Visualization/VisualizationTabWidget.h @@ -38,6 +38,7 @@ public: // IVisualizationWidget interface void accept(IVisualizationWidgetVisitor *visitor) override; bool canDrop(const Variable &variable) const override; + bool contains(const Variable &variable) const override; QString name() const override; private: diff --git a/gui/include/Visualization/VisualizationWidget.h b/gui/include/Visualization/VisualizationWidget.h index 874203d..378b3e3 100644 --- a/gui/include/Visualization/VisualizationWidget.h +++ b/gui/include/Visualization/VisualizationWidget.h @@ -26,6 +26,7 @@ public: // IVisualizationWidget interface void accept(IVisualizationWidgetVisitor *visitor) override; bool canDrop(const Variable &variable) const override; + bool contains(const Variable &variable) const override; QString name() const override; public slots: @@ -37,6 +38,9 @@ public slots: void attachVariableMenu(QMenu *menu, const QVector > &variables) noexcept; + /// Slot called when a variable is about to be deleted from SciQlop + void onVariableAboutToBeDeleted(std::shared_ptr variable) noexcept; + private: Ui::VisualizationWidget *ui; }; diff --git a/gui/include/Visualization/VisualizationZoneWidget.h b/gui/include/Visualization/VisualizationZoneWidget.h index 7732a9f..da13188 100644 --- a/gui/include/Visualization/VisualizationZoneWidget.h +++ b/gui/include/Visualization/VisualizationZoneWidget.h @@ -35,6 +35,7 @@ public: // IVisualizationWidget interface void accept(IVisualizationWidgetVisitor *visitor) override; bool canDrop(const Variable &variable) const override; + bool contains(const Variable &variable) const override; QString name() const override; private: diff --git a/gui/include/Visualization/operations/MenuBuilder.h b/gui/include/Visualization/operations/MenuBuilder.h index d5ee390..cb78fb7 100644 --- a/gui/include/Visualization/operations/MenuBuilder.h +++ b/gui/include/Visualization/operations/MenuBuilder.h @@ -27,8 +27,9 @@ public: /** * Adds a new menu to the current menu * @param name the name of the menu + * @param icon the icon of the menu (can be null) */ - void addMenu(const QString &name); + void addMenu(const QString &name, const QIcon &icon = {}); /// Adds a separator to the current menu. The separator is added only if the menu already /// contains entries diff --git a/gui/include/Visualization/operations/RemoveVariableOperation.h b/gui/include/Visualization/operations/RemoveVariableOperation.h new file mode 100644 index 0000000..055e1cf --- /dev/null +++ b/gui/include/Visualization/operations/RemoveVariableOperation.h @@ -0,0 +1,41 @@ +#ifndef SCIQLOP_REMOVEVARIABLEOPERATION_H +#define SCIQLOP_REMOVEVARIABLEOPERATION_H + +#include "Visualization/IVisualizationWidgetVisitor.h" + +#include + +#include + +#include + +class Variable; + +Q_DECLARE_LOGGING_CATEGORY(LOG_RemoveVariableOperation) + +/** + * @brief The RemoveVariableOperation class defines an operation that traverses all of visualization + * widgets to remove a variable if they contain it + */ +class RemoveVariableOperation : public IVisualizationWidgetVisitor { +public: + /** + * Ctor + * @param variable the variable to remove from widgets + */ + explicit RemoveVariableOperation(std::shared_ptr variable); + + void visitEnter(VisualizationWidget *widget) override final; + void visitLeave(VisualizationWidget *widget) override final; + void visitEnter(VisualizationTabWidget *tabWidget) override final; + void visitLeave(VisualizationTabWidget *tabWidget) override final; + void visitEnter(VisualizationZoneWidget *zoneWidget) override final; + void visitLeave(VisualizationZoneWidget *zoneWidget) override final; + void visit(VisualizationGraphWidget *graphWidget) override final; + +private: + class RemoveVariableOperationPrivate; + spimpl::unique_impl_ptr impl; +}; + +#endif // SCIQLOP_REMOVEVARIABLEOPERATION_H diff --git a/gui/resources/icones/plot.png b/gui/resources/icones/plot.png new file mode 100644 index 0000000000000000000000000000000000000000..bd783f0b1aa15db3d7b0fc906377baf9eb7b8ff1 GIT binary patch literal 2319 zc$@(b3GnubP)Vv8@pZF13U)w#HohPWHHhs&)vA1)Cb%FObA~cokI`s8u=U3 zC;bSVAG%^Xfu+Fj zEf)iS67DVg0hy^g3z_Tpp$j+~Sb@wm4g}P>+EZI2SVWlV+g{*d;3VR%RZK_T-c12C z4*`!x)>~;V#=r4*1GkfYDt0VzIbr%N4Qg3rtQed<0{VA?sHBOt31o z@SM!XZ%TI^)f-MtLf+&-%9m?da@84_Ncqp^UgY<8Y;x7^oD2Lyx$^x5oRVB|V#-eP zY(skWb>J{$#89T3TY#zQC8uF2bJT!4(Z{SDensz^hT$La&!CZ$luW`OBZk_ z0H&FRp`sU3)$+{2o_WBvtQRYe_Hp2{IMG~?0Fnr)+g zzxksv26zcwJq!Y;?N z70+twHyZ5>aHb-kH+_XPgfEaik}k}l0>LQS8Q?_6JoGgpdZY8`(7L!pxXLTqrWYp^7{#*y8?db$srSs45&NGJs~9a;K*T%_2&x z)Qaak^Yoobbgh%h4gWPDT=4ip(c6O3VR2q6t)kK=QdHGn3nb|>up z)8hI9WshE7WPpA}9u_ife_Ve;|B9-@fg-2&D)N|uM9eCS@3QD~E&khT;3JPbKlb>4 z!M%6yQ*S{iGQciH9!DTYq06FKL38D!Ncps{RHe#Tt8NhWUa0VS5AFl

O?!PP7(b)?_%N5UlPfd1Goq%p5MULZ6RX7?p6P?yf_=^C zUzN~Q!2ov`=xCJ&soAhu8y{$CVtu&{FazD&ujyP@f+^?Zpa}t6px`R>@Vof z7u1O^Bo=_CK7OVGn?QZ&LAE<<3jGc>{p5{;Hf-(?aCH`?fw=>H!5^Vn%f$=P-#NIR z^uyyQOh9hY)|%kX9AYCdAN^Nw0J&MMF=%_f|D;va`%7>(FQ{g{IsY$#JH8>s$f(#hzD zdL3ti#gxBcvmc4KU&UeK1?Yl4cC-m@!LMT0Q<0c?$imLkgl+haFhQA{v__^E$rm+i zDzc=jS@bd!jG*l8nj_QeNEp==qlIIE`$^OAjWvSWdjb%tU`)?y?tF;MY&CD$Wo*?e(*YC*Ylby&U z%^qY#(T$wXpN{(}-JGlgE=3oUp%$EqoHEY+menC;{}RMvD*uL(Z%Wc^j4=}ob0rdW zBzNQaqygYT;Bcg|%mhlNAsZ;m&K%}UpY#7E-AR}UN^=?#Q$Kg3x}+_@RkR+4nh89) zkm?#?Gjh~xv{8(iAOI&L*Qu6SZx5LUkwY6x(4BEK69i&1a--(k=x!_ZP2VDuS3bwJ z%mjfs7&$@nIC7FUWXEwkGBmvbI5ME-TAH9Pd-SFtCzaeyTmE8I_zkC>39RuugjOb4kyVkAoJqhd pz;D2{nY9>(VHk#C7=}?R{ssq@VDHBZ4Ql`Z002ovPDHLkV1nbSE))O& literal 0 Hc$@(vi?D9I=v)#+WYAbdWCyjp@Q`V0 zpaaSnjyf}4e3R)o|G2)r*V=0zz6aLT>{-0)TkqcgIxjE`!!QiPFe*n~YynC}1LJ@( zz$joCa2?P9^aa|1HlP(a2^9x`>U>WJYGKPWyNWc#g zuhM%;t-uDPonZu^AFv$woA{O8TRI192AaZzp_=X(bD0r&}d0}mi0c_+I5b{-j1=#TW}Z$P?o6M)HGx<-1|)CsHrUiO@C zVVMK`gTJ@zcVwjQ9%QUP4RydRz!GGnvE8H2^(nQLf_eBEzHJ3I0aFM&S1}TKdk=Wf z+zGr9SZ}VGL;A{Z0alXzP;4Jy0e;#nuV$=07u-d<&wd-Q4j7!Z@NU#2UDhL{Gr_8? zg~wzp>4tQh$zOMB5b`E>ki1-rGFKge0VMxyo=1Lv`(&=#od6S(H~r9$njNKh zzxh|A9{3Pl96Eq$F~s_0Il4lhr#P*BE!P5j(Z%EI7(#t90NG@rDewzXlxD|d^uyn? zqbT*jGW3nUJP-2tVgy)|9evO(-EJd)!@HsA3+zN^f~irIreGer0`**AF_;QRY8hahB9E#!{<`zC;@Mk* zsc@v00mdlu*yBM*nb5>zY%mp$)H1**MIHxy2q_UQ$f8*nMu!yQLM;OfQ{-WXEndkH z$LEFyRpCG_189aRPo&hKnMBDdJ(jXet}%(;4XkB=21Oocd3(afL~1=rKaT7s%@pw>^oaYY_uJm@GB z4aiI3!m*G-T&QIL%^O{nJpiuUs(AL#U@9D`Wq|#PJSO`PQX(|Bk7(i?gx(C`+7p;g zh0n+9fx8vY=6WJcv*juJv}TUjjeFc~jHK}*y{!rSUXjnkX@!)8Cg3*5XOENPHUQ{W zwmh0vNJ-Gd;oD#;JTV&gPgy(uPvR~j&A7+x*+?2yXbys05lLfS7>{ns`KCBBb*#m` zKnJMy#Lz3a$12yY|4W&K&eeGw*Uy3>$oz?GoCl-Rk=B17P`0`q@dgA#vtq5 zG{18XM9`TfgMmNL8K4k-|5|KDSJ=bo_7@b1I&_;rJCR}E=!-zp(1a{^))e|n3i`>r z3fg0HJAo&oDD}*0^aX#Na!nV{MSthuPD;`}?vLD}tu?`#7-9o31N~R99l2SpG-zAC z|D{zF`%7>y$!<#77(;AmHj>N)>nY}^a4z~czZ2;>m2#G}KQf__!~`EA=j|7PI;6pu z=APkiDCxl11Y~1FlA!D*|BFcnqwnff&II#Ge#2%PvW6g!-Naew4t=b&37#iiV0Mz9 zGxJ6P@8GxMD`A2pH)(ZG9}w@ygSb6DS#hETBv}au_rH$mLVIgD?{$ zW*Tyla_mZVNr!+Z=(!teCP>L_@@s^H$d!3l>&2J}JTMixPBqDVyU)~tY}$AX-5y6X zfhPtdH)?)??zYmjX*V)>m1et^nZPsGAvHGLMpTeJ&lf}*U^YeaS` zPejfm8jBoYF|_M%{kl>+a{TIP@=IX& z#Y|wB2@ErVftkR-OkiLpFfbDsm>A7xk$BL$&Ma5T$8 z80iRMf@d-5b!bZH}G_1ErwwjhG7_nVHApg0T{%Y4KAj$mH+?%07*qo IM6N<$f&hXLX#fBK literal 0 Hc$@icones/delete.png icones/openInspector.png icones/next.png + icones/plot.png icones/previous.png + icones/unplot.png diff --git a/gui/src/SqpApplication.cpp b/gui/src/SqpApplication.cpp index 4c221ba..a1554ca 100644 --- a/gui/src/SqpApplication.cpp +++ b/gui/src/SqpApplication.cpp @@ -32,6 +32,10 @@ public: connect(m_VariableController.get(), SIGNAL(variableCreated(std::shared_ptr)), m_VisualizationController.get(), SIGNAL(variableCreated(std::shared_ptr))); + connect(m_VariableController.get(), + SIGNAL(variableAboutToBeDeleted(std::shared_ptr)), + m_VisualizationController.get(), + SIGNAL(variableAboutToBeDeleted(std::shared_ptr)), Qt::DirectConnection); m_DataSourceController->moveToThread(&m_DataSourceControllerThread); m_VariableController->moveToThread(&m_VariableControllerThread); diff --git a/gui/src/Variable/VariableInspectorWidget.cpp b/gui/src/Variable/VariableInspectorWidget.cpp index d26beb4..fe00434 100644 --- a/gui/src/Variable/VariableInspectorWidget.cpp +++ b/gui/src/Variable/VariableInspectorWidget.cpp @@ -68,8 +68,8 @@ void VariableInspectorWidget::onTableMenuRequested(const QPoint &pos) noexcept // Adds menu-specific actions if (!selectedVariables.isEmpty()) { // 'Delete' action - auto deleteFun = []() { - /// @todo ALX : call variable deletion + auto deleteFun = [&selectedVariables]() { + sqpApp->variableController().deleteVariables(selectedVariables); }; tableMenu.addSeparator(); diff --git a/gui/src/Visualization/VisualizationGraphWidget.cpp b/gui/src/Visualization/VisualizationGraphWidget.cpp index 2c37585..d96af5b 100644 --- a/gui/src/Visualization/VisualizationGraphWidget.cpp +++ b/gui/src/Visualization/VisualizationGraphWidget.cpp @@ -141,6 +141,18 @@ bool VisualizationGraphWidget::canDrop(const Variable &variable) const return true; } +bool VisualizationGraphWidget::contains(const Variable &variable) const +{ + // Finds the variable among the keys of the map + auto variablePtr = &variable; + auto findVariable + = [variablePtr](const auto &entry) { return variablePtr == entry.first.get(); }; + + auto end = impl->m_VariableToPlotMultiMap.cend(); + auto it = std::find_if(impl->m_VariableToPlotMultiMap.cbegin(), end, findVariable); + return it != end; +} + QString VisualizationGraphWidget::name() const { return ui->graphNameLabel->text(); diff --git a/gui/src/Visualization/VisualizationTabWidget.cpp b/gui/src/Visualization/VisualizationTabWidget.cpp index 6040c45..f516cbb 100644 --- a/gui/src/Visualization/VisualizationTabWidget.cpp +++ b/gui/src/Visualization/VisualizationTabWidget.cpp @@ -93,6 +93,12 @@ bool VisualizationTabWidget::canDrop(const Variable &variable) const return true; } +bool VisualizationTabWidget::contains(const Variable &variable) const +{ + Q_UNUSED(variable); + return false; +} + QString VisualizationTabWidget::name() const { return impl->m_Name; diff --git a/gui/src/Visualization/VisualizationWidget.cpp b/gui/src/Visualization/VisualizationWidget.cpp index 77eec9c..2b29114 100644 --- a/gui/src/Visualization/VisualizationWidget.cpp +++ b/gui/src/Visualization/VisualizationWidget.cpp @@ -4,6 +4,7 @@ #include "Visualization/VisualizationTabWidget.h" #include "Visualization/VisualizationZoneWidget.h" #include "Visualization/operations/GenerateVariableMenuOperation.h" +#include "Visualization/operations/RemoveVariableOperation.h" #include "Visualization/qcustomplot.h" #include "ui_VisualizationWidget.h" @@ -101,6 +102,12 @@ bool VisualizationWidget::canDrop(const Variable &variable) const return false; } +bool VisualizationWidget::contains(const Variable &variable) const +{ + Q_UNUSED(variable); + return false; +} + QString VisualizationWidget::name() const { return QStringLiteral("MainView"); @@ -127,3 +134,10 @@ void VisualizationWidget::attachVariableMenu( "selected"); } } + +void VisualizationWidget::onVariableAboutToBeDeleted(std::shared_ptr variable) noexcept +{ + // Calls the operation of removing all references to the variable in the visualization + auto removeVariableOperation = RemoveVariableOperation{variable}; + accept(&removeVariableOperation); +} diff --git a/gui/src/Visualization/VisualizationZoneWidget.cpp b/gui/src/Visualization/VisualizationZoneWidget.cpp index 7fe59b7..355dbf4 100644 --- a/gui/src/Visualization/VisualizationZoneWidget.cpp +++ b/gui/src/Visualization/VisualizationZoneWidget.cpp @@ -99,6 +99,12 @@ bool VisualizationZoneWidget::canDrop(const Variable &variable) const return true; } +bool VisualizationZoneWidget::contains(const Variable &variable) const +{ + Q_UNUSED(variable); + return false; +} + QString VisualizationZoneWidget::name() const { return ui->zoneNameLabel->text(); diff --git a/gui/src/Visualization/operations/GenerateVariableMenuOperation.cpp b/gui/src/Visualization/operations/GenerateVariableMenuOperation.cpp index dec20d8..ad85543 100644 --- a/gui/src/Visualization/operations/GenerateVariableMenuOperation.cpp +++ b/gui/src/Visualization/operations/GenerateVariableMenuOperation.cpp @@ -14,52 +14,71 @@ Q_LOGGING_CATEGORY(LOG_GenerateVariableMenuOperation, "GenerateVariableMenuOpera struct GenerateVariableMenuOperation::GenerateVariableMenuOperationPrivate { explicit GenerateVariableMenuOperationPrivate(QMenu *menu, std::shared_ptr variable) - : m_Variable{variable}, m_MenuBuilder{menu} + : m_Variable{variable}, m_PlotMenuBuilder{menu}, m_UnplotMenuBuilder{menu} { } void visitRootEnter() { // Creates the root menu - m_MenuBuilder.addMenu(QObject::tr("Plot")); + m_PlotMenuBuilder.addMenu(QObject::tr("Plot"), QIcon{":/icones/plot.png"}); + m_UnplotMenuBuilder.addMenu(QObject::tr("Unplot"), QIcon{":/icones/unplot.png"}); } void visitRootLeave() { // Closes the root menu - m_MenuBuilder.closeMenu(); + m_PlotMenuBuilder.closeMenu(); + m_UnplotMenuBuilder.closeMenu(); } void visitNodeEnter(const IVisualizationWidget &container) { // Opens a new menu associated to the node - m_MenuBuilder.addMenu(container.name()); + m_PlotMenuBuilder.addMenu(container.name()); + m_UnplotMenuBuilder.addMenu(container.name()); } template - void visitNodeLeave(const IVisualizationWidget &container, const QString &actionName, - ActionFun actionFunction) + void visitNodeLeavePlot(const IVisualizationWidget &container, const QString &actionName, + ActionFun actionFunction) { if (m_Variable && container.canDrop(*m_Variable)) { - m_MenuBuilder.addSeparator(); - m_MenuBuilder.addAction(actionName, actionFunction); + m_PlotMenuBuilder.addSeparator(); + m_PlotMenuBuilder.addAction(actionName, actionFunction); } // Closes the menu associated to the node - m_MenuBuilder.closeMenu(); + m_PlotMenuBuilder.closeMenu(); + } + + void visitNodeLeaveUnplot() + { + // Closes the menu associated to the node + m_UnplotMenuBuilder.closeMenu(); } template - void visitLeaf(const IVisualizationWidget &container, const QString &actionName, - ActionFun actionFunction) + void visitLeafPlot(const IVisualizationWidget &container, const QString &actionName, + ActionFun actionFunction) { if (m_Variable && container.canDrop(*m_Variable)) { - m_MenuBuilder.addAction(actionName, actionFunction); + m_PlotMenuBuilder.addAction(actionName, actionFunction); + } + } + + template + void visitLeafUnplot(const IVisualizationWidget &container, const QString &actionName, + ActionFun actionFunction) + { + if (m_Variable && container.contains(*m_Variable)) { + m_UnplotMenuBuilder.addAction(actionName, actionFunction); } } std::shared_ptr m_Variable; - MenuBuilder m_MenuBuilder; + MenuBuilder m_PlotMenuBuilder; ///< Builder for the 'Plot' menu + MenuBuilder m_UnplotMenuBuilder; ///< Builder for the 'Unplot' menu }; GenerateVariableMenuOperation::GenerateVariableMenuOperation(QMenu *menu, @@ -73,6 +92,7 @@ void GenerateVariableMenuOperation::visitEnter(VisualizationWidget *widget) // VisualizationWidget is not intended to accommodate a variable Q_UNUSED(widget) + // 'Plot' and 'Unplot' menus impl->visitRootEnter(); } @@ -81,12 +101,14 @@ void GenerateVariableMenuOperation::visitLeave(VisualizationWidget *widget) // VisualizationWidget is not intended to accommodate a variable Q_UNUSED(widget) + // 'Plot' and 'Unplot' menus impl->visitRootLeave(); } void GenerateVariableMenuOperation::visitEnter(VisualizationTabWidget *tabWidget) { if (tabWidget) { + // 'Plot' and 'Unplot' menus impl->visitNodeEnter(*tabWidget); } else { @@ -98,9 +120,13 @@ void GenerateVariableMenuOperation::visitEnter(VisualizationTabWidget *tabWidget void GenerateVariableMenuOperation::visitLeave(VisualizationTabWidget *tabWidget) { if (tabWidget) { - impl->visitNodeLeave( + // 'Plot' menu + impl->visitNodeLeavePlot( *tabWidget, QObject::tr("Open in a new zone"), [ var = impl->m_Variable, tabWidget ]() { tabWidget->createZone(var); }); + + // 'Unplot' menu + impl->visitNodeLeaveUnplot(); } else { qCCritical(LOG_GenerateVariableMenuOperation(), @@ -111,6 +137,7 @@ void GenerateVariableMenuOperation::visitLeave(VisualizationTabWidget *tabWidget void GenerateVariableMenuOperation::visitEnter(VisualizationZoneWidget *zoneWidget) { if (zoneWidget) { + // 'Plot' and 'Unplot' menus impl->visitNodeEnter(*zoneWidget); } else { @@ -122,9 +149,13 @@ void GenerateVariableMenuOperation::visitEnter(VisualizationZoneWidget *zoneWidg void GenerateVariableMenuOperation::visitLeave(VisualizationZoneWidget *zoneWidget) { if (zoneWidget) { - impl->visitNodeLeave( + // 'Plot' menu + impl->visitNodeLeavePlot( *zoneWidget, QObject::tr("Open in a new graph"), [ var = impl->m_Variable, zoneWidget ]() { zoneWidget->createGraph(var); }); + + // 'Unplot' menu + impl->visitNodeLeaveUnplot(); } else { qCCritical(LOG_GenerateVariableMenuOperation(), @@ -135,9 +166,15 @@ void GenerateVariableMenuOperation::visitLeave(VisualizationZoneWidget *zoneWidg void GenerateVariableMenuOperation::visit(VisualizationGraphWidget *graphWidget) { if (graphWidget) { - impl->visitLeaf( + // 'Plot' menu + impl->visitLeafPlot( *graphWidget, QObject::tr("Open in %1").arg(graphWidget->name()), [ var = impl->m_Variable, graphWidget ]() { graphWidget->addVariableUsingGraph(var); }); + + // 'Unplot' menu + impl->visitLeafUnplot( + *graphWidget, QObject::tr("Remove from %1").arg(graphWidget->name()), + [ var = impl->m_Variable, graphWidget ]() { graphWidget->removeVariable(var); }); } else { qCCritical(LOG_GenerateVariableMenuOperation(), diff --git a/gui/src/Visualization/operations/MenuBuilder.cpp b/gui/src/Visualization/operations/MenuBuilder.cpp index 23b8e01..3d21803 100644 --- a/gui/src/Visualization/operations/MenuBuilder.cpp +++ b/gui/src/Visualization/operations/MenuBuilder.cpp @@ -12,10 +12,10 @@ MenuBuilder::MenuBuilder(QMenu *menu) } } -void MenuBuilder::addMenu(const QString &name) +void MenuBuilder::addMenu(const QString &name, const QIcon &icon) { if (auto currMenu = currentMenu()) { - m_Menus.push(currMenu->addMenu(name)); + m_Menus.push(currMenu->addMenu(icon, name)); } else { qCCritical(LOG_MenuBuilder()) << QObject::tr("No current menu to attach the new menu"); diff --git a/gui/src/Visualization/operations/RemoveVariableOperation.cpp b/gui/src/Visualization/operations/RemoveVariableOperation.cpp new file mode 100644 index 0000000..1196957 --- /dev/null +++ b/gui/src/Visualization/operations/RemoveVariableOperation.cpp @@ -0,0 +1,70 @@ +#include "Visualization/operations/RemoveVariableOperation.h" +#include "Visualization/VisualizationGraphWidget.h" + +#include + +Q_LOGGING_CATEGORY(LOG_RemoveVariableOperation, "RemoveVariableOperation") + +struct RemoveVariableOperation::RemoveVariableOperationPrivate { + explicit RemoveVariableOperationPrivate(std::shared_ptr variable) + : m_Variable(variable) + { + } + + std::shared_ptr m_Variable; +}; + +RemoveVariableOperation::RemoveVariableOperation(std::shared_ptr variable) + : impl{spimpl::make_unique_impl(variable)} +{ +} + +void RemoveVariableOperation::visitEnter(VisualizationWidget *widget) +{ + // VisualizationWidget is not intended to contain a variable + Q_UNUSED(widget) +} + +void RemoveVariableOperation::visitLeave(VisualizationWidget *widget) +{ + // VisualizationWidget is not intended to contain a variable + Q_UNUSED(widget) +} + +void RemoveVariableOperation::visitEnter(VisualizationTabWidget *tabWidget) +{ + // VisualizationTabWidget is not intended to contain a variable + Q_UNUSED(tabWidget) +} + +void RemoveVariableOperation::visitLeave(VisualizationTabWidget *tabWidget) +{ + // VisualizationTabWidget is not intended to contain a variable + Q_UNUSED(tabWidget) +} + +void RemoveVariableOperation::visitEnter(VisualizationZoneWidget *zoneWidget) +{ + // VisualizationZoneWidget is not intended to contain a variable + Q_UNUSED(zoneWidget) +} + +void RemoveVariableOperation::visitLeave(VisualizationZoneWidget *zoneWidget) +{ + // VisualizationZoneWidget is not intended to contain a variable + Q_UNUSED(zoneWidget) +} + +void RemoveVariableOperation::visit(VisualizationGraphWidget *graphWidget) +{ + if (graphWidget) { + // If the widget contains the variable, removes it + if (impl->m_Variable && graphWidget->contains(*impl->m_Variable)) { + graphWidget->removeVariable(impl->m_Variable); + } + } + else { + qCCritical(LOG_RemoveVariableOperation(), + "Can't visit VisualizationGraphWidget : the widget is null"); + } +}