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
This commit is contained in:
Roman Telezhynskyi 2019-07-15 19:56:57 +03:00
parent 8424775d63
commit bdaba68a7e
9 changed files with 455 additions and 34 deletions

View File

@ -30,6 +30,8 @@
#include "ui_vwidgetgroups.h" #include "ui_vwidgetgroups.h"
#include "../vtools/dialogs/tools/dialoggroup.h" #include "../vtools/dialogs/tools/dialoggroup.h"
#include "../vtools/undocommands/delgroup.h" #include "../vtools/undocommands/delgroup.h"
#include "../vtools/undocommands/changegroupvisivility.h"
#include "../vtools/undocommands/changemultiplegroupsvisivility.h"
#include "../vpatterndb/vcontainer.h" #include "../vpatterndb/vcontainer.h"
#include <QMenu> #include <QMenu>
@ -59,13 +61,72 @@ VWidgetGroups::~VWidgetGroups()
delete ui; 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); QTableWidgetItem *item = ui->tableWidget->item(row, 0);
if (item)
{
(visible) ? item->setIcon(QIcon(QStringLiteral("://icon/16x16/open_eye.png"))) (visible) ? item->setIcon(QIcon(QStringLiteral("://icon/16x16/open_eye.png")))
: item->setIcon(QIcon(QStringLiteral("://icon/16x16/closed_eye.png"))); : item->setIcon(QIcon(QStringLiteral("://icon/16x16/closed_eye.png")));
}
});
qApp->getUndoStack()->push(changeGroup);
}
//---------------------------------------------------------------------------------------------------------------------
void VWidgetGroups::SetMultipleGroupsVisibility(const QVector<vidtype> &groups, bool visible) const
{
auto *changeGroups = new ChangeMultipleGroupsVisivility(doc, groups, visible);
connect(changeGroups, &ChangeMultipleGroupsVisivility::UpdateMultipleGroups, this,
[this](const QMap<vidtype, bool> &groups)
{
QMap<vidtype, bool>::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); QTableWidgetItem *item = ui->tableWidget->item(row, column);
const quint32 id = item->data(Qt::UserRole).toUInt(); const quint32 id = item->data(Qt::UserRole).toUInt();
const bool visible = not doc->GetGroupVisivility(id); SetGroupVisivility(id, not doc->GetGroupVisivility(id));
SetIconValue(id, visible, item);
} }
//--------------------------------------------------------------------------------------------------------------------- //---------------------------------------------------------------------------------------------------------------------
@ -108,6 +168,20 @@ void VWidgetGroups::CtxMenu(const QPoint &pos)
item = ui->tableWidget->item(row, 0); item = ui->tableWidget->item(row, 0);
const quint32 id = item->data(Qt::UserRole).toUInt(); 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<QMenu> menu(new QMenu()); QScopedPointer<QMenu> menu(new QMenu());
QAction *triggerVisibilityMenu = doc->GetGroupVisivility(id) ? QAction *triggerVisibilityMenu = doc->GetGroupVisivility(id) ?
menu->addAction(QIcon(QStringLiteral("://icon/16x16/closed_eye.png")), tr("Hide")) : 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")); QAction *actionDelete = menu->addAction(QIcon::fromTheme(editDeleteIcon), tr("Delete"));
menu->addSeparator(); menu->addSeparator();
QAction *actionHideAll = menu->addAction(tr("Hide All")); QAction *actionHideAll = menu->addAction(tr("Hide All"));
actionHideAll->setEnabled(MultipleChangeVisibilityTo(false));
QAction *actionShowAll = menu->addAction(tr("Show All")); QAction *actionShowAll = menu->addAction(tr("Show All"));
actionShowAll->setEnabled(MultipleChangeVisibilityTo(true));
QAction *selectedAction = menu->exec(ui->tableWidget->viewport()->mapToGlobal(pos)); QAction *selectedAction = menu->exec(ui->tableWidget->viewport()->mapToGlobal(pos));
if (selectedAction == triggerVisibilityMenu) if (selectedAction == triggerVisibilityMenu)
{ {
SetIconValue(id, not doc->GetGroupVisivility(id), item); SetGroupVisivility(id, not doc->GetGroupVisivility(id));
} }
else if (selectedAction == actionRename) else if (selectedAction == actionRename)
{ {
@ -148,27 +224,51 @@ void VWidgetGroups::CtxMenu(const QPoint &pos)
} }
else if (selectedAction == actionHideAll) else if (selectedAction == actionHideAll)
{//all groups in "group" make unvisible {//all groups in "group" make unvisible
if (ui->tableWidget->rowCount() < 1)
{
return;
}
QVector<vidtype> groups;
groups.reserve(ui->tableWidget->rowCount());
for (int r = 0; r < ui->tableWidget->rowCount(); ++r) for (int r = 0; r < ui->tableWidget->rowCount(); ++r)
{ {
QTableWidgetItem *rowItem = ui->tableWidget->item(r, 0); QTableWidgetItem *rowItem = ui->tableWidget->item(r, 0);
quint32 i = rowItem->data(Qt::UserRole).toUInt(); quint32 i = rowItem->data(Qt::UserRole).toUInt();
if (doc->GetGroupVisivility(i)) if (doc->GetGroupVisivility(i))
{ {
SetIconValue(i, false, rowItem); groups.append(i);
} }
} }
if (not groups.isEmpty())
{
SetMultipleGroupsVisibility(groups, false);
}
} }
else if (selectedAction == actionShowAll) else if (selectedAction == actionShowAll)
{//all groups in "group" make visible {//all groups in "group" make visible
if (ui->tableWidget->rowCount() < 1)
{
return;
}
QVector<vidtype> groups;
groups.reserve(ui->tableWidget->rowCount());
for (int r = 0; r < ui->tableWidget->rowCount(); ++r) for (int r = 0; r < ui->tableWidget->rowCount(); ++r)
{ {
QTableWidgetItem *rowItem = ui->tableWidget->item(r, 0); QTableWidgetItem *rowItem = ui->tableWidget->item(r, 0);
quint32 i = rowItem->data(Qt::UserRole).toUInt(); quint32 i = rowItem->data(Qt::UserRole).toUInt();
if (not doc->GetGroupVisivility(i)) if (not doc->GetGroupVisivility(i))
{ {
SetIconValue(i, true, rowItem); groups.append(i);
} }
} }
if (not groups.isEmpty())
{
SetMultipleGroupsVisibility(groups, true);
}
} }
} }

View File

@ -30,6 +30,7 @@
#define VWIDGETGROUPS_H #define VWIDGETGROUPS_H
#include <QWidget> #include <QWidget>
#include "../vmisc/typedef.h"
class QTableWidgetItem; class QTableWidgetItem;
class VAbstractPattern; class VAbstractPattern;
@ -61,7 +62,10 @@ private:
VAbstractPattern *doc; VAbstractPattern *doc;
void FillTable(const QMap<quint32, QPair<QString, bool> > &groups); void FillTable(const QMap<quint32, QPair<QString, bool> > &groups);
void SetIconValue(quint32, bool visible, QTableWidgetItem *item)const; void SetGroupVisivility(vidtype id, bool visible) const;
void SetMultipleGroupsVisibility(const QVector<vidtype> &groups, bool visible) const;
int GroupRow(vidtype id) const;
}; };
#endif // VWIDGETGROUPS_H #endif // VWIDGETGROUPS_H

View File

@ -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) QString VAbstractPattern::PieceDrawName(quint32 id)
{ {

View File

@ -202,7 +202,6 @@ public:
QDomElement RemoveItemFromGroup(quint32 toolId, quint32 objectId, quint32 groupId); QDomElement RemoveItemFromGroup(quint32 toolId, quint32 objectId, quint32 groupId);
bool GroupIsEmpty(quint32 id); bool GroupIsEmpty(quint32 id);
bool GetGroupVisivility(quint32 id); bool GetGroupVisivility(quint32 id);
void SetGroupVisivility(quint32 id, bool visible);
QString PieceDrawName(quint32 id); QString PieceDrawName(quint32 id);

View File

@ -0,0 +1,95 @@
/************************************************************************
**
** @file changegroupvisivility.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @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
** <https://bitbucket.org/dismine/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#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);
}
}

View File

@ -0,0 +1,55 @@
/************************************************************************
**
** @file changegroupvisivility.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @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
** <https://bitbucket.org/dismine/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#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

View File

@ -0,0 +1,131 @@
/************************************************************************
**
** @file changemultiplegroupsvisivility.cpp
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @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
** <https://bitbucket.org/dismine/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#include "changemultiplegroupsvisivility.h"
#include "../vmisc/vabstractapplication.h"
#include "../vwidgets/vmaingraphicsview.h"
//---------------------------------------------------------------------------------------------------------------------
ChangeMultipleGroupsVisivility::ChangeMultipleGroupsVisivility(VAbstractPattern *doc, const QVector<vidtype> &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<vidtype, bool> groupsState;
QMap<vidtype, bool>::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<vidtype, bool> 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);
}
}

View File

@ -0,0 +1,55 @@
/************************************************************************
**
** @file changemultiplegroupsvisivility.h
** @author Roman Telezhynskyi <dismine(at)gmail.com>
** @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
** <https://bitbucket.org/dismine/valentina> 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 <http://www.gnu.org/licenses/>.
**
*************************************************************************/
#ifndef CHANGEMULTIPLEGROUPSVISIVILITY_H
#define CHANGEMULTIPLEGROUPSVISIVILITY_H
#include "vundocommand.h"
class ChangeMultipleGroupsVisivility : public VUndoCommand
{
Q_OBJECT
public:
ChangeMultipleGroupsVisivility(VAbstractPattern *doc, const QVector<vidtype> &groups, bool visible,
QUndoCommand *parent = nullptr);
virtual ~ChangeMultipleGroupsVisivility() =default;
virtual void undo() override;
virtual void redo() override;
signals:
void UpdateMultipleGroups(const QMap<vidtype, bool> &groups);
private:
Q_DISABLE_COPY(ChangeMultipleGroupsVisivility)
QVector<vidtype> m_groups;
bool m_newVisibility{true};
QMap<vidtype, bool> m_oldVisibility{};
const QString m_nameActivDraw{};
};
#endif // CHANGEMULTIPLEGROUPSVISIVILITY_H

View File

@ -4,6 +4,8 @@
HEADERS += \ HEADERS += \
$$PWD/addtocalc.h \ $$PWD/addtocalc.h \
$$PWD/addpatternpiece.h \ $$PWD/addpatternpiece.h \
$$PWD/changegroupvisivility.h \
$$PWD/changemultiplegroupsvisivility.h \
$$PWD/movespoint.h \ $$PWD/movespoint.h \
$$PWD/movespline.h \ $$PWD/movespline.h \
$$PWD/movesplinepath.h \ $$PWD/movesplinepath.h \
@ -34,6 +36,8 @@ HEADERS += \
SOURCES += \ SOURCES += \
$$PWD/addtocalc.cpp \ $$PWD/addtocalc.cpp \
$$PWD/addpatternpiece.cpp \ $$PWD/addpatternpiece.cpp \
$$PWD/changegroupvisivility.cpp \
$$PWD/changemultiplegroupsvisivility.cpp \
$$PWD/movespoint.cpp \ $$PWD/movespoint.cpp \
$$PWD/movespline.cpp \ $$PWD/movespline.cpp \
$$PWD/movesplinepath.cpp \ $$PWD/movesplinepath.cpp \