From bdaba68a7ef8387d7b396a72d55bccc55ae1134b Mon Sep 17 00:00:00 2001 From: Roman Telezhynskyi Date: Mon, 15 Jul 2019 19:56:57 +0300 Subject: [PATCH] Allow to undo change of group visibility. Added single group visibility change and multiple groups visibility change, options hide all/show all. Improved speed for hide all/show all options. --HG-- branch : develop --- src/app/valentina/dialogs/vwidgetgroups.cpp | 120 ++++++++++++++-- src/app/valentina/dialogs/vwidgetgroups.h | 6 +- src/libs/ifc/xml/vabstractpattern.cpp | 22 --- src/libs/ifc/xml/vabstractpattern.h | 1 - .../undocommands/changegroupvisivility.cpp | 95 +++++++++++++ .../undocommands/changegroupvisivility.h | 55 ++++++++ .../changemultiplegroupsvisivility.cpp | 131 ++++++++++++++++++ .../changemultiplegroupsvisivility.h | 55 ++++++++ src/libs/vtools/undocommands/undocommands.pri | 4 + 9 files changed, 455 insertions(+), 34 deletions(-) create mode 100644 src/libs/vtools/undocommands/changegroupvisivility.cpp create mode 100644 src/libs/vtools/undocommands/changegroupvisivility.h create mode 100644 src/libs/vtools/undocommands/changemultiplegroupsvisivility.cpp create mode 100644 src/libs/vtools/undocommands/changemultiplegroupsvisivility.h diff --git a/src/app/valentina/dialogs/vwidgetgroups.cpp b/src/app/valentina/dialogs/vwidgetgroups.cpp index 5ab64a276..c73ca4b84 100644 --- a/src/app/valentina/dialogs/vwidgetgroups.cpp +++ b/src/app/valentina/dialogs/vwidgetgroups.cpp @@ -30,6 +30,8 @@ #include "ui_vwidgetgroups.h" #include "../vtools/dialogs/tools/dialoggroup.h" #include "../vtools/undocommands/delgroup.h" +#include "../vtools/undocommands/changegroupvisivility.h" +#include "../vtools/undocommands/changemultiplegroupsvisivility.h" #include "../vpatterndb/vcontainer.h" #include @@ -59,13 +61,72 @@ VWidgetGroups::~VWidgetGroups() delete ui; } //---------------------------------------------------------------------------------------------------------------------- -void VWidgetGroups::SetIconValue(quint32 id, bool visible, QTableWidgetItem *item) const +void VWidgetGroups::SetGroupVisivility(vidtype id, bool visible) const { - SCASSERT(item != nullptr) + ChangeGroupVisivility *changeGroup = new ChangeGroupVisivility(doc, id, visible); + connect(changeGroup, &ChangeGroupVisivility::UpdateGroup, this, [this](vidtype id, bool visible) + { + int row = GroupRow(id); + if (row == -1) + { + return; + } - doc->SetGroupVisivility(id, visible); - (visible) ? item->setIcon(QIcon(QStringLiteral("://icon/16x16/open_eye.png"))) - : item->setIcon(QIcon(QStringLiteral("://icon/16x16/closed_eye.png"))); + QTableWidgetItem *item = ui->tableWidget->item(row, 0); + if (item) + { + (visible) ? item->setIcon(QIcon(QStringLiteral("://icon/16x16/open_eye.png"))) + : item->setIcon(QIcon(QStringLiteral("://icon/16x16/closed_eye.png"))); + } + }); + qApp->getUndoStack()->push(changeGroup); +} + +//--------------------------------------------------------------------------------------------------------------------- +void VWidgetGroups::SetMultipleGroupsVisibility(const QVector &groups, bool visible) const +{ + auto *changeGroups = new ChangeMultipleGroupsVisivility(doc, groups, visible); + connect(changeGroups, &ChangeMultipleGroupsVisivility::UpdateMultipleGroups, this, + [this](const QMap &groups) + { + QMap::const_iterator i = groups.constBegin(); + while (i != groups.constEnd()) + { + int row = GroupRow(i.key()); + if (row == -1) + { + ++i; + continue; + } + + QTableWidgetItem *item = ui->tableWidget->item(row, 0); + if (item) + { + (i.value()) ? item->setIcon(QIcon(QStringLiteral("://icon/16x16/open_eye.png"))) + : item->setIcon(QIcon(QStringLiteral("://icon/16x16/closed_eye.png"))); + } + ++i; + } + + }); + qApp->getUndoStack()->push(changeGroups); +} + +//--------------------------------------------------------------------------------------------------------------------- +int VWidgetGroups::GroupRow(vidtype id) const +{ + for (int r = 0; r < ui->tableWidget->rowCount(); ++r) + { + QTableWidgetItem *item = ui->tableWidget->item(r, 0); + SCASSERT(item != nullptr) + + if (id == item->data(Qt::UserRole).toUInt()) + { + return r; + } + } + + return -1; } //--------------------------------------------------------------------------------------------------------------------- @@ -77,8 +138,7 @@ void VWidgetGroups::GroupVisibilityChanged(int row, int column) } QTableWidgetItem *item = ui->tableWidget->item(row, column); const quint32 id = item->data(Qt::UserRole).toUInt(); - const bool visible = not doc->GetGroupVisivility(id); - SetIconValue(id, visible, item); + SetGroupVisivility(id, not doc->GetGroupVisivility(id)); } //--------------------------------------------------------------------------------------------------------------------- @@ -108,6 +168,20 @@ void VWidgetGroups::CtxMenu(const QPoint &pos) item = ui->tableWidget->item(row, 0); const quint32 id = item->data(Qt::UserRole).toUInt(); + auto MultipleChangeVisibilityTo = [this](bool visibility) + { + for (int r = 0; r < ui->tableWidget->rowCount(); ++r) + { + QTableWidgetItem *rowItem = ui->tableWidget->item(r, 0); + if (rowItem and visibility != doc->GetGroupVisivility(rowItem->data(Qt::UserRole).toUInt())) + { + return true; + } + } + + return false; + }; + QScopedPointer menu(new QMenu()); QAction *triggerVisibilityMenu = doc->GetGroupVisivility(id) ? menu->addAction(QIcon(QStringLiteral("://icon/16x16/closed_eye.png")), tr("Hide")) : @@ -117,13 +191,15 @@ void VWidgetGroups::CtxMenu(const QPoint &pos) QAction *actionDelete = menu->addAction(QIcon::fromTheme(editDeleteIcon), tr("Delete")); menu->addSeparator(); QAction *actionHideAll = menu->addAction(tr("Hide All")); + actionHideAll->setEnabled(MultipleChangeVisibilityTo(false)); QAction *actionShowAll = menu->addAction(tr("Show All")); + actionShowAll->setEnabled(MultipleChangeVisibilityTo(true)); QAction *selectedAction = menu->exec(ui->tableWidget->viewport()->mapToGlobal(pos)); if (selectedAction == triggerVisibilityMenu) { - SetIconValue(id, not doc->GetGroupVisivility(id), item); + SetGroupVisivility(id, not doc->GetGroupVisivility(id)); } else if (selectedAction == actionRename) { @@ -148,27 +224,51 @@ void VWidgetGroups::CtxMenu(const QPoint &pos) } else if (selectedAction == actionHideAll) {//all groups in "group" make unvisible + if (ui->tableWidget->rowCount() < 1) + { + return; + } + + QVector groups; + groups.reserve(ui->tableWidget->rowCount()); for (int r = 0; r < ui->tableWidget->rowCount(); ++r) { QTableWidgetItem *rowItem = ui->tableWidget->item(r, 0); quint32 i = rowItem->data(Qt::UserRole).toUInt(); if (doc->GetGroupVisivility(i)) { - SetIconValue(i, false, rowItem); + groups.append(i); } } + + if (not groups.isEmpty()) + { + SetMultipleGroupsVisibility(groups, false); + } } else if (selectedAction == actionShowAll) {//all groups in "group" make visible + if (ui->tableWidget->rowCount() < 1) + { + return; + } + + QVector groups; + groups.reserve(ui->tableWidget->rowCount()); for (int r = 0; r < ui->tableWidget->rowCount(); ++r) { QTableWidgetItem *rowItem = ui->tableWidget->item(r, 0); quint32 i = rowItem->data(Qt::UserRole).toUInt(); if (not doc->GetGroupVisivility(i)) { - SetIconValue(i, true, rowItem); + groups.append(i); } } + + if (not groups.isEmpty()) + { + SetMultipleGroupsVisibility(groups, true); + } } } diff --git a/src/app/valentina/dialogs/vwidgetgroups.h b/src/app/valentina/dialogs/vwidgetgroups.h index c524513b3..ef480db38 100644 --- a/src/app/valentina/dialogs/vwidgetgroups.h +++ b/src/app/valentina/dialogs/vwidgetgroups.h @@ -30,6 +30,7 @@ #define VWIDGETGROUPS_H #include +#include "../vmisc/typedef.h" class QTableWidgetItem; class VAbstractPattern; @@ -61,7 +62,10 @@ private: VAbstractPattern *doc; void FillTable(const QMap > &groups); - void SetIconValue(quint32, bool visible, QTableWidgetItem *item)const; + void SetGroupVisivility(vidtype id, bool visible) const; + void SetMultipleGroupsVisibility(const QVector &groups, bool visible) const; + + int GroupRow(vidtype id) const; }; #endif // VWIDGETGROUPS_H diff --git a/src/libs/ifc/xml/vabstractpattern.cpp b/src/libs/ifc/xml/vabstractpattern.cpp index 677b3d79a..7f454aa15 100644 --- a/src/libs/ifc/xml/vabstractpattern.cpp +++ b/src/libs/ifc/xml/vabstractpattern.cpp @@ -2713,28 +2713,6 @@ bool VAbstractPattern::GetGroupVisivility(quint32 id) } } -//--------------------------------------------------------------------------------------------------------------------- -void VAbstractPattern::SetGroupVisivility(quint32 id, bool visible) -{ - QDomElement group = elementById(id, TagGroup); - if (group.isElement()) - { - SetAttribute(group, AttrVisible, visible); - modified = true; - emit patternChanged(false); - - QDomElement groups = CreateGroups(); - if (not groups.isNull()) - { - ParseGroups(groups); - } - } - else - { - qDebug("Can't get group by id = %u.", id); - } -} - //--------------------------------------------------------------------------------------------------------------------- QString VAbstractPattern::PieceDrawName(quint32 id) { diff --git a/src/libs/ifc/xml/vabstractpattern.h b/src/libs/ifc/xml/vabstractpattern.h index 7919ca544..1781ad6e3 100644 --- a/src/libs/ifc/xml/vabstractpattern.h +++ b/src/libs/ifc/xml/vabstractpattern.h @@ -202,7 +202,6 @@ public: QDomElement RemoveItemFromGroup(quint32 toolId, quint32 objectId, quint32 groupId); bool GroupIsEmpty(quint32 id); bool GetGroupVisivility(quint32 id); - void SetGroupVisivility(quint32 id, bool visible); QString PieceDrawName(quint32 id); diff --git a/src/libs/vtools/undocommands/changegroupvisivility.cpp b/src/libs/vtools/undocommands/changegroupvisivility.cpp new file mode 100644 index 000000000..aa2757b7c --- /dev/null +++ b/src/libs/vtools/undocommands/changegroupvisivility.cpp @@ -0,0 +1,95 @@ +/************************************************************************ + ** + ** @file changegroupvisivility.cpp + ** @author Roman Telezhynskyi + ** @date 14 7, 2019 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentina project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2019 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ +#include "changegroupvisivility.h" +#include "../vmisc/vabstractapplication.h" +#include "../vwidgets/vmaingraphicsview.h" + +//--------------------------------------------------------------------------------------------------------------------- +ChangeGroupVisivility::ChangeGroupVisivility(VAbstractPattern *doc, vidtype id, bool visible, QUndoCommand *parent) + : VUndoCommand(QDomElement(), doc, parent), + m_newVisibility(visible), + m_nameActivDraw(doc->GetNameActivPP()) +{ + setText(tr("change group visibility")); + nodeId = id; + QDomElement group = doc->elementById(nodeId, VAbstractPattern::TagGroup); + if (group.isElement()) + { + m_oldVisibility = doc->GetParametrBool(group, VAbstractPattern::AttrVisible, trueStr); + } + else + { + qDebug("Can't get group by id = %u.", id); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +ChangeGroupVisivility::~ChangeGroupVisivility() +{} + +//--------------------------------------------------------------------------------------------------------------------- +void ChangeGroupVisivility::undo() +{ + qCDebug(vUndo, "Undo."); + + Do(m_oldVisibility); +} + +//--------------------------------------------------------------------------------------------------------------------- +void ChangeGroupVisivility::redo() +{ + qCDebug(vUndo, "Redo."); + + Do(m_newVisibility); +} + +//--------------------------------------------------------------------------------------------------------------------- +void ChangeGroupVisivility::Do(bool visible) +{ + doc->ChangeActivPP(m_nameActivDraw);//Without this user will not see this change + + QDomElement group = doc->elementById(nodeId, VAbstractPattern::TagGroup); + if (group.isElement()) + { + doc->SetAttribute(group, VAbstractPattern::AttrVisible, visible); + + QDomElement groups = doc->CreateGroups(); + if (not groups.isNull()) + { + doc->ParseGroups(groups); + } + + emit UpdateGroup(nodeId, visible); + + VMainGraphicsView::NewSceneRect(qApp->getCurrentScene(), qApp->getSceneView()); + } + else + { + qDebug("Can't get group by id = %u.", nodeId); + } +} diff --git a/src/libs/vtools/undocommands/changegroupvisivility.h b/src/libs/vtools/undocommands/changegroupvisivility.h new file mode 100644 index 000000000..cdf1db93d --- /dev/null +++ b/src/libs/vtools/undocommands/changegroupvisivility.h @@ -0,0 +1,55 @@ +/************************************************************************ + ** + ** @file changegroupvisivility.h + ** @author Roman Telezhynskyi + ** @date 14 7, 2019 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentina project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2019 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ +#ifndef CHANGEGROUPVISIVILITY_H +#define CHANGEGROUPVISIVILITY_H + +#include "vundocommand.h" + +class ChangeGroupVisivility : public VUndoCommand +{ + Q_OBJECT +public: + ChangeGroupVisivility(VAbstractPattern *doc, vidtype id, bool visible, QUndoCommand *parent = nullptr); + virtual ~ChangeGroupVisivility(); + virtual void undo() override; + virtual void redo() override; + +signals: + void UpdateGroup(vidtype id, bool visible); + +private: + Q_DISABLE_COPY(ChangeGroupVisivility) + + bool m_oldVisibility{true}; + bool m_newVisibility{true}; + const QString m_nameActivDraw{}; + + void Do(bool visible); +}; + +#endif // CHANGEGROUPVISIVILITY_H diff --git a/src/libs/vtools/undocommands/changemultiplegroupsvisivility.cpp b/src/libs/vtools/undocommands/changemultiplegroupsvisivility.cpp new file mode 100644 index 000000000..8e0e1a523 --- /dev/null +++ b/src/libs/vtools/undocommands/changemultiplegroupsvisivility.cpp @@ -0,0 +1,131 @@ +/************************************************************************ + ** + ** @file changemultiplegroupsvisivility.cpp + ** @author Roman Telezhynskyi + ** @date 15 7, 2019 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentina project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2019 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ +#include "changemultiplegroupsvisivility.h" +#include "../vmisc/vabstractapplication.h" +#include "../vwidgets/vmaingraphicsview.h" + +//--------------------------------------------------------------------------------------------------------------------- +ChangeMultipleGroupsVisivility::ChangeMultipleGroupsVisivility(VAbstractPattern *doc, const QVector &groups, + bool visible, QUndoCommand *parent) + : VUndoCommand(QDomElement(), doc, parent), + m_groups(groups), + m_newVisibility(visible), + m_nameActivDraw(doc->GetNameActivPP()) +{ + setText(tr("change multiple groups visibility")); + + for(auto & groupId : m_groups) + { + QDomElement group = doc->elementById(groupId, VAbstractPattern::TagGroup); + if (group.isElement()) + { + m_oldVisibility.insert(groupId, doc->GetParametrBool(group, VAbstractPattern::AttrVisible, trueStr)); + } + else + { + qDebug("Can't get group by id = %u.", groupId); + } + } + +} + +//--------------------------------------------------------------------------------------------------------------------- +void ChangeMultipleGroupsVisivility::undo() +{ + qCDebug(vUndo, "Undo."); + + doc->ChangeActivPP(m_nameActivDraw);//Without this user will not see this change + + QMap groupsState; + + QMap::const_iterator i = m_oldVisibility.constBegin(); + while (i != m_oldVisibility.constEnd()) + { + QDomElement group = doc->elementById(i.key(), VAbstractPattern::TagGroup); + if (group.isElement()) + { + doc->SetAttribute(group, VAbstractPattern::AttrVisible, i.value()); + groupsState.insert(i.key(), i.value()); + } + else + { + qDebug("Can't get group by id = %u.", i.key()); + } + ++i; + } + + if (not groupsState.isEmpty()) + { + QDomElement groups = doc->CreateGroups(); + if (not groups.isNull()) + { + doc->ParseGroups(groups); + } + + VMainGraphicsView::NewSceneRect(qApp->getCurrentScene(), qApp->getSceneView()); + + emit UpdateMultipleGroups(groupsState); + } +} + +//--------------------------------------------------------------------------------------------------------------------- +void ChangeMultipleGroupsVisivility::redo() +{ + qCDebug(vUndo, "ChangeMultipleGroupsVisivility::redo"); + + doc->ChangeActivPP(m_nameActivDraw);//Without this user will not see this change + + QMap groupsState; + + for (auto& groupId : m_groups) + { + QDomElement group = doc->elementById(groupId, VAbstractPattern::TagGroup); + if (group.isElement()) + { + doc->SetAttribute(group, VAbstractPattern::AttrVisible, m_newVisibility); + groupsState.insert(groupId, m_newVisibility); + } + else + { + qDebug("Can't get group by id = %u.", groupId); + } + } + + if (not groupsState.isEmpty()) + { + QDomElement groups = doc->CreateGroups(); + if (not groups.isNull()) + { + doc->ParseGroups(groups); + } + + VMainGraphicsView::NewSceneRect(qApp->getCurrentScene(), qApp->getSceneView()); + + emit UpdateMultipleGroups(groupsState); + } +} diff --git a/src/libs/vtools/undocommands/changemultiplegroupsvisivility.h b/src/libs/vtools/undocommands/changemultiplegroupsvisivility.h new file mode 100644 index 000000000..2b258cb68 --- /dev/null +++ b/src/libs/vtools/undocommands/changemultiplegroupsvisivility.h @@ -0,0 +1,55 @@ +/************************************************************************ + ** + ** @file changemultiplegroupsvisivility.h + ** @author Roman Telezhynskyi + ** @date 15 7, 2019 + ** + ** @brief + ** @copyright + ** This source code is part of the Valentina project, a pattern making + ** program, whose allow create and modeling patterns of clothing. + ** Copyright (C) 2019 Valentina project + ** All Rights Reserved. + ** + ** Valentina is free software: you can redistribute it and/or modify + ** it under the terms of the GNU General Public License as published by + ** the Free Software Foundation, either version 3 of the License, or + ** (at your option) any later version. + ** + ** Valentina is distributed in the hope that it will be useful, + ** but WITHOUT ANY WARRANTY; without even the implied warranty of + ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + ** GNU General Public License for more details. + ** + ** You should have received a copy of the GNU General Public License + ** along with Valentina. If not, see . + ** + *************************************************************************/ +#ifndef CHANGEMULTIPLEGROUPSVISIVILITY_H +#define CHANGEMULTIPLEGROUPSVISIVILITY_H + +#include "vundocommand.h" + +class ChangeMultipleGroupsVisivility : public VUndoCommand +{ + Q_OBJECT +public: + ChangeMultipleGroupsVisivility(VAbstractPattern *doc, const QVector &groups, bool visible, + QUndoCommand *parent = nullptr); + virtual ~ChangeMultipleGroupsVisivility() =default; + virtual void undo() override; + virtual void redo() override; + +signals: + void UpdateMultipleGroups(const QMap &groups); + +private: + Q_DISABLE_COPY(ChangeMultipleGroupsVisivility) + + QVector m_groups; + bool m_newVisibility{true}; + QMap m_oldVisibility{}; + const QString m_nameActivDraw{}; +}; + +#endif // CHANGEMULTIPLEGROUPSVISIVILITY_H diff --git a/src/libs/vtools/undocommands/undocommands.pri b/src/libs/vtools/undocommands/undocommands.pri index f69bd070f..26657d61b 100644 --- a/src/libs/vtools/undocommands/undocommands.pri +++ b/src/libs/vtools/undocommands/undocommands.pri @@ -4,6 +4,8 @@ HEADERS += \ $$PWD/addtocalc.h \ $$PWD/addpatternpiece.h \ + $$PWD/changegroupvisivility.h \ + $$PWD/changemultiplegroupsvisivility.h \ $$PWD/movespoint.h \ $$PWD/movespline.h \ $$PWD/movesplinepath.h \ @@ -34,6 +36,8 @@ HEADERS += \ SOURCES += \ $$PWD/addtocalc.cpp \ $$PWD/addpatternpiece.cpp \ + $$PWD/changegroupvisivility.cpp \ + $$PWD/changemultiplegroupsvisivility.cpp \ $$PWD/movespoint.cpp \ $$PWD/movespline.cpp \ $$PWD/movesplinepath.cpp \