From 1949fe4bf9e132e208766142400bf0d18d6762ce Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Thu, 2 Jul 2015 15:47:12 +0300 Subject: [PATCH 01/16] Add the configuration widget for extended commands --- apps/opencs/CMakeLists.txt | 2 +- .../world/extendedcommandconfigurator.cpp | 184 ++++++++++++++++++ .../world/extendedcommandconfigurator.hpp | 68 +++++++ 3 files changed, 253 insertions(+), 1 deletion(-) create mode 100644 apps/opencs/view/world/extendedcommandconfigurator.cpp create mode 100644 apps/opencs/view/world/extendedcommandconfigurator.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index dc042cb99..c933cbf9d 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -64,7 +64,7 @@ opencs_units (view/world table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator cellcreator referenceablecreator referencecreator scenesubview infocreator scriptedit dialoguesubview previewsubview regionmap dragrecordtable nestedtable - dialoguespinbox recordbuttonbar + dialoguespinbox recordbuttonbar extendedcommandconfigurator ) opencs_units_noqt (view/world diff --git a/apps/opencs/view/world/extendedcommandconfigurator.cpp b/apps/opencs/view/world/extendedcommandconfigurator.cpp new file mode 100644 index 000000000..dfdb5f573 --- /dev/null +++ b/apps/opencs/view/world/extendedcommandconfigurator.cpp @@ -0,0 +1,184 @@ +#include "extendedcommandconfigurator.hpp" + +#include +#include +#include +#include + +#include "../../model/world/commanddispatcher.hpp" +#include "../../model/world/universalid.hpp" + +namespace +{ + QString getTypeGroupTitle(CSVWorld::ExtendedCommandConfigurator::Mode mode) + { + static const QString title = "Tables affected by "; + QString titleSuffix = "Extended Delete"; + if (mode == CSVWorld::ExtendedCommandConfigurator::Mode_Revert) + { + titleSuffix = "Extended Revert"; + } + return title + titleSuffix; + } +} + +CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Document &document, + const CSMWorld::UniversalId &id, + QWidget *parent) + : QWidget(parent), + mNumUsedCheckBoxes(0), + mMode(Mode_None) +{ + mCommandDispatcher = new CSMWorld::CommandDispatcher(document, id, this); + + mPerformButton = new QPushButton("Perform", this); + mPerformButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + connect(mPerformButton, SIGNAL(clicked(bool)), this, SLOT(performExtendedCommand())); + + mCancelButton = new QPushButton("Cancel", this); + mCancelButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); + connect(mCancelButton, SIGNAL(clicked(bool)), this, SLOT(done())); + + mButtonLayout = new QHBoxLayout(); + mButtonLayout->setAlignment(Qt::AlignCenter); + mButtonLayout->addWidget(mPerformButton); + mButtonLayout->addWidget(mCancelButton); + + mTypeGroup = new QGroupBox(this); + + QGridLayout *groupLayout = new QGridLayout(mTypeGroup); + groupLayout->setAlignment(Qt::AlignCenter); + mTypeGroup->setLayout(groupLayout); + + QVBoxLayout *mainLayout = new QVBoxLayout(this); + mainLayout->setSizeConstraint(QLayout::SetNoConstraint); + mainLayout->addWidget(mTypeGroup); + mainLayout->addLayout(mButtonLayout); +} + +CSVWorld::ExtendedCommandConfigurator::~ExtendedCommandConfigurator() +{ + delete mButtonLayout; +} + +void CSVWorld::ExtendedCommandConfigurator::configure(CSVWorld::ExtendedCommandConfigurator::Mode mode) +{ + mMode = mode; + if (mMode != Mode_None) + { + mTypeGroup->setTitle(getTypeGroupTitle(mMode)); + setupCheckBoxes(mCommandDispatcher->getExtendedTypes()); + setupGroupLayout(); + } +} + +void CSVWorld::ExtendedCommandConfigurator::resizeEvent(QResizeEvent *event) +{ + QWidget::resizeEvent(event); + setupGroupLayout(); +} + +void CSVWorld::ExtendedCommandConfigurator::setupGroupLayout() +{ + if (mMode == Mode_None) + { + return; + } + + int groupWidth = mTypeGroup->geometry().width(); + QGridLayout *layout = qobject_cast(mTypeGroup->layout()); + + // One row of checkboxes with enough space - the setup is over + if (mNumUsedCheckBoxes > 0 && layout->rowCount() == 1 && groupWidth >= mTypeGroup->sizeHint().width()) + { + return; + } + + // Find the optimal number of rows to place the checkboxes within the available space + int divider = 1; + do + { + while (layout->itemAt(0) != NULL) + { + layout->removeItem(layout->itemAt(0)); + } + + int counter = 0; + int itemsPerRow = mNumUsedCheckBoxes / divider; + CheckBoxMap::const_iterator current = mTypeCheckBoxes.begin(); + CheckBoxMap::const_iterator end = mTypeCheckBoxes.end(); + for (; current != end; ++current) + { + if (current->first->isVisible()) + { + int row = counter / itemsPerRow; + int column = counter - (counter / itemsPerRow) * itemsPerRow; + layout->addWidget(current->first, row, column); + } + ++counter; + } + divider *= 2; + } + while (groupWidth < mTypeGroup->sizeHint().width()); +} + +void CSVWorld::ExtendedCommandConfigurator::setupCheckBoxes(const std::vector &types) +{ + // Make sure that we have enough checkboxes + int numTypes = static_cast(types.size()); + int numCheckBoxes = static_cast(mTypeCheckBoxes.size()); + if (numTypes > numCheckBoxes) + { + for (int i = numTypes - numCheckBoxes; i > 0; --i) + { + mTypeCheckBoxes.insert(std::make_pair(new QCheckBox(this), CSMWorld::UniversalId::Type_None)); + } + } + + // Set up the checkboxes + int counter = 0; + CheckBoxMap::iterator current = mTypeCheckBoxes.begin(); + CheckBoxMap::iterator end = mTypeCheckBoxes.end(); + for (; current != end; ++current) + { + if (counter < numTypes) + { + CSMWorld::UniversalId type = types[counter]; + current->first->setText(QString::fromUtf8(type.getTypeName().c_str())); + current->first->setChecked(true); + current->second = type; + ++counter; + } + else + { + current->first->hide(); + } + } + mNumUsedCheckBoxes = counter - 1; +} + +void CSVWorld::ExtendedCommandConfigurator::performExtendedCommand() +{ + std::vector types; + + CheckBoxMap::const_iterator current = mTypeCheckBoxes.begin(); + CheckBoxMap::const_iterator end = mTypeCheckBoxes.end(); + for (; current != end; ++current) + { + if (current->first->isChecked()) + { + types.push_back(current->second); + } + } + + mCommandDispatcher->setExtendedTypes(types); + if (mMode == Mode_Delete) + { + mCommandDispatcher->executeExtendedDelete(); + } + else + { + mCommandDispatcher->executeExtendedRevert(); + } + emit done(); +} diff --git a/apps/opencs/view/world/extendedcommandconfigurator.hpp b/apps/opencs/view/world/extendedcommandconfigurator.hpp new file mode 100644 index 000000000..2feec14a7 --- /dev/null +++ b/apps/opencs/view/world/extendedcommandconfigurator.hpp @@ -0,0 +1,68 @@ +#ifndef CSVWORLD_EXTENDEDCOMMANDCONFIGURATOR_HPP +#define CSVWORLD_EXTENDEDCOMMANDCONFIGURATOR_HPP + +#include + +#include + +class QPushButton; +class QGroupBox; +class QCheckBox; +class QHBoxLayout; + +namespace CSMDoc +{ + class Document; +} + +namespace CSMWorld +{ + class CommandDispatcher; + class UniversalId; +} + +namespace CSVWorld +{ + class ExtendedCommandConfigurator : public QWidget + { + Q_OBJECT + + public: + enum Mode { Mode_None, Mode_Delete, Mode_Revert }; + + private: + typedef std::map CheckBoxMap; + + QPushButton *mPerformButton; + QPushButton *mCancelButton; + QHBoxLayout *mButtonLayout; + QGroupBox *mTypeGroup; + CheckBoxMap mTypeCheckBoxes; + int mNumUsedCheckBoxes; + + Mode mMode; + CSMWorld::CommandDispatcher *mCommandDispatcher; + + void setupGroupLayout(); + void setupCheckBoxes(const std::vector &types); + + public: + ExtendedCommandConfigurator(CSMDoc::Document &document, + const CSMWorld::UniversalId &id, + QWidget *parent = 0); + virtual ~ExtendedCommandConfigurator(); + + void configure(Mode mode); + + protected: + virtual void resizeEvent(QResizeEvent *event); + + private slots: + void performExtendedCommand(); + + signals: + void done(); + }; +} + +#endif From ba762ec1c1739bf0c86f727e8875efd7a2f3c4bf Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Thu, 2 Jul 2015 17:21:47 +0300 Subject: [PATCH 02/16] Add the configuration widget to the bottom box --- apps/opencs/view/world/tablebottombox.cpp | 37 ++++++++++++++++++----- apps/opencs/view/world/tablebottombox.hpp | 17 +++++++++-- 2 files changed, 43 insertions(+), 11 deletions(-) diff --git a/apps/opencs/view/world/tablebottombox.cpp b/apps/opencs/view/world/tablebottombox.cpp index dc3a6cc76..eab6b07b3 100644 --- a/apps/opencs/view/world/tablebottombox.cpp +++ b/apps/opencs/view/world/tablebottombox.cpp @@ -39,11 +39,19 @@ void CSVWorld::TableBottomBox::updateStatus() } } +void CSVWorld::TableBottomBox::extendedConfigRequest(CSVWorld::ExtendedCommandConfigurator::Mode mode) +{ + mExtendedConfigurator->configure (mode); + mLayout->setCurrentWidget (mExtendedConfigurator); + mEditMode = EditMode_ExtendedConfig; + setVisible (true); +} + CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFactory, CSMDoc::Document& document, const CSMWorld::UniversalId& id, QWidget *parent) -: QWidget (parent), mShowStatusBar (false), mCreating (false) +: QWidget (parent), mShowStatusBar (false), mEditMode(EditMode_None) { for (int i=0; i<4; ++i) mStatusCount[i] = 0; @@ -69,11 +77,15 @@ CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFacto { mLayout->addWidget (mCreator); - connect (mCreator, SIGNAL (done()), this, SLOT (createRequestDone())); + connect (mCreator, SIGNAL (done()), this, SLOT (requestDone())); connect (mCreator, SIGNAL (requestFocus (const std::string&)), this, SIGNAL (requestFocus (const std::string&))); } + + mExtendedConfigurator = new ExtendedCommandConfigurator (document, id, this); + mLayout->addWidget (mExtendedConfigurator); + connect (mExtendedConfigurator, SIGNAL (done()), this, SLOT (requestDone())); } void CSVWorld::TableBottomBox::setEditLock (bool locked) @@ -91,7 +103,7 @@ void CSVWorld::TableBottomBox::setStatusBar (bool show) { if (show!=mShowStatusBar) { - setVisible (show || mCreating); + setVisible (show || (mEditMode != EditMode_None)); mShowStatusBar = show; @@ -105,7 +117,7 @@ bool CSVWorld::TableBottomBox::canCreateAndDelete() const return mCreator; } -void CSVWorld::TableBottomBox::createRequestDone() +void CSVWorld::TableBottomBox::requestDone() { if (!mShowStatusBar) setVisible (false); @@ -113,8 +125,7 @@ void CSVWorld::TableBottomBox::createRequestDone() updateStatus(); mLayout->setCurrentWidget (mStatusBar); - - mCreating = false; + mEditMode = EditMode_None; } void CSVWorld::TableBottomBox::selectionSizeChanged (int size) @@ -158,7 +169,7 @@ void CSVWorld::TableBottomBox::createRequest() mCreator->toggleWidgets(true); mLayout->setCurrentWidget (mCreator); setVisible (true); - mCreating = true; + mEditMode = EditMode_Creation; mCreator->focus(); } @@ -170,6 +181,16 @@ void CSVWorld::TableBottomBox::cloneRequest(const std::string& id, mLayout->setCurrentWidget(mCreator); mCreator->toggleWidgets(false); setVisible (true); - mCreating = true; + mEditMode = EditMode_Creation; mCreator->focus(); } + +void CSVWorld::TableBottomBox::extendedDeleteConfigRequest() +{ + extendedConfigRequest(ExtendedCommandConfigurator::Mode_Delete); +} + +void CSVWorld::TableBottomBox::extendedRevertConfigRequest() +{ + extendedConfigRequest(ExtendedCommandConfigurator::Mode_Revert); +} diff --git a/apps/opencs/view/world/tablebottombox.hpp b/apps/opencs/view/world/tablebottombox.hpp index a7d009c42..d2fb865e7 100644 --- a/apps/opencs/view/world/tablebottombox.hpp +++ b/apps/opencs/view/world/tablebottombox.hpp @@ -4,10 +4,11 @@ #include #include +#include "extendedcommandconfigurator.hpp" + class QLabel; class QStackedLayout; class QStatusBar; -class QUndoStack; namespace CSMDoc { @@ -23,12 +24,17 @@ namespace CSVWorld { Q_OBJECT + enum EditMode { EditMode_None, EditMode_Creation, EditMode_ExtendedConfig }; + bool mShowStatusBar; QLabel *mStatus; QStatusBar *mStatusBar; int mStatusCount[4]; + + EditMode mEditMode; Creator *mCreator; - bool mCreating; + ExtendedCommandConfigurator *mExtendedConfigurator; + QStackedLayout *mLayout; private: @@ -39,6 +45,8 @@ namespace CSVWorld void updateStatus(); + void extendedConfigRequest(ExtendedCommandConfigurator::Mode mode); + public: TableBottomBox (const CreatorFactoryBase& creatorFactory, @@ -65,7 +73,7 @@ namespace CSVWorld private slots: - void createRequestDone(); + void requestDone(); ///< \note This slot being called does not imply success. public slots: @@ -80,6 +88,9 @@ namespace CSVWorld void createRequest(); void cloneRequest(const std::string& id, const CSMWorld::UniversalId::Type type); + + void extendedDeleteConfigRequest(); + void extendedRevertConfigRequest(); }; } From fcf69555f4bf382aa808179a5fafb89df7feaaa1 Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Thu, 2 Jul 2015 20:41:32 +0300 Subject: [PATCH 03/16] Add the user setting for enabling the configuration of extended commands --- apps/opencs/model/settings/usersettings.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 1bfc6e85b..cb001fea9 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -215,6 +215,12 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() "Jump to the added or cloned record."); jumpToAdded->setDefaultValue (defaultValue); jumpToAdded->setDeclaredValues (jumpValues); + + Setting *extendedConfig = createSetting (Type_CheckBox, "extended-config", + "Enable configuration of the extended delete/revert"); + extendedConfig->setDefaultValue("false"); + extendedConfig->setToolTip("Enables the ability to specify tables that will be affected by " + "the extended delete/revert command"); } declareSection ("report-input", "Report Input"); From b8772c6902ec22f80a3f1d4850db626417c1898b Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Thu, 2 Jul 2015 20:44:59 +0300 Subject: [PATCH 04/16] Add the ability to configure extended commands for tables --- .../world/extendedcommandconfigurator.cpp | 6 +- .../world/extendedcommandconfigurator.hpp | 2 +- apps/opencs/view/world/table.cpp | 70 +++++++++++++------ apps/opencs/view/world/table.hpp | 10 +++ apps/opencs/view/world/tablebottombox.cpp | 13 ++-- apps/opencs/view/world/tablebottombox.hpp | 7 +- apps/opencs/view/world/tablesubview.cpp | 5 ++ 7 files changed, 79 insertions(+), 34 deletions(-) diff --git a/apps/opencs/view/world/extendedcommandconfigurator.cpp b/apps/opencs/view/world/extendedcommandconfigurator.cpp index dfdb5f573..6ba26634b 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.cpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.cpp @@ -37,7 +37,7 @@ CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Docum mCancelButton = new QPushButton("Cancel", this); mCancelButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - connect(mCancelButton, SIGNAL(clicked(bool)), this, SLOT(done())); + connect(mCancelButton, SIGNAL(clicked(bool)), this, SIGNAL(done())); mButtonLayout = new QHBoxLayout(); mButtonLayout->setAlignment(Qt::AlignCenter); @@ -61,12 +61,14 @@ CSVWorld::ExtendedCommandConfigurator::~ExtendedCommandConfigurator() delete mButtonLayout; } -void CSVWorld::ExtendedCommandConfigurator::configure(CSVWorld::ExtendedCommandConfigurator::Mode mode) +void CSVWorld::ExtendedCommandConfigurator::configure(CSVWorld::ExtendedCommandConfigurator::Mode mode, + const std::vector &selectedIds) { mMode = mode; if (mMode != Mode_None) { mTypeGroup->setTitle(getTypeGroupTitle(mMode)); + mCommandDispatcher->setSelection(selectedIds); setupCheckBoxes(mCommandDispatcher->getExtendedTypes()); setupGroupLayout(); } diff --git a/apps/opencs/view/world/extendedcommandconfigurator.hpp b/apps/opencs/view/world/extendedcommandconfigurator.hpp index 2feec14a7..dd2477444 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.hpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.hpp @@ -52,7 +52,7 @@ namespace CSVWorld QWidget *parent = 0); virtual ~ExtendedCommandConfigurator(); - void configure(Mode mode); + void configure(Mode mode, const std::vector &selectedIds); protected: virtual void resizeEvent(QResizeEvent *event); diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index ba691131b..353bd50d2 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -32,28 +32,14 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) { // configure dispatcher - QModelIndexList selectedRows = selectionModel()->selectedRows(); - - std::vector records; - - int columnIndex = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Id); - - for (QModelIndexList::const_iterator iter (selectedRows.begin()); iter!=selectedRows.end(); - ++iter) - { - int row = mProxyModel->mapToSource (mProxyModel->index (iter->row(), 0)).row(); - - records.push_back (mModel->data ( - mModel->index (row, columnIndex)).toString().toUtf8().constData()); - } - - mDispatcher->setSelection (records); + mDispatcher->setSelection (getSelectedIds()); std::vector extendedTypes = mDispatcher->getExtendedTypes(); mDispatcher->setExtendedTypes (extendedTypes); // create context menu + QModelIndexList selectedRows = selectionModel()->selectedRows(); QMenu menu (this); /// \todo add menu items for select all and clear selection @@ -375,16 +361,12 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, connect (mPreviewAction, SIGNAL (triggered()), this, SLOT (previewRecord())); addAction (mPreviewAction); - /// \todo add a user option, that redirects the extended action to an input panel (in - /// the bottom bar) that lets the user select which record collections should be - /// modified. - mExtendedDeleteAction = new QAction (tr ("Extended Delete Record"), this); - connect (mExtendedDeleteAction, SIGNAL (triggered()), mDispatcher, SLOT (executeExtendedDelete())); + connect (mExtendedDeleteAction, SIGNAL (triggered()), this, SLOT (executeExtendedDelete())); addAction (mExtendedDeleteAction); mExtendedRevertAction = new QAction (tr ("Extended Revert Record"), this); - connect (mExtendedRevertAction, SIGNAL (triggered()), mDispatcher, SLOT (executeExtendedRevert())); + connect (mExtendedRevertAction, SIGNAL (triggered()), this, SLOT (executeExtendedRevert())); addAction (mExtendedRevertAction); connect (mProxyModel, SIGNAL (rowsRemoved (const QModelIndex&, int, int)), @@ -430,6 +412,22 @@ CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const mModel->data (mModel->index (row, idColumn)).toString().toUtf8().constData()); } +std::vector CSVWorld::Table::getSelectedIds() const +{ + std::vector ids; + QModelIndexList selectedRows = selectionModel()->selectedRows(); + int columnIndex = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Id); + + for (QModelIndexList::const_iterator iter (selectedRows.begin()); + iter != selectedRows.end(); + ++iter) + { + int row = mProxyModel->mapToSource (mProxyModel->index (iter->row(), 0)).row(); + ids.push_back (mModel->data (mModel->index (row, columnIndex)).toString().toUtf8().constData()); + } + return ids; +} + void CSVWorld::Table::editRecord() { if (!mEditLock || (mModel->getFeatures() & CSMWorld::IdTableBase::Feature_Constant)) @@ -562,6 +560,34 @@ void CSVWorld::Table::previewRecord() } } +void CSVWorld::Table::executeExtendedDelete() +{ + CSMSettings::UserSettings &settings = CSMSettings::UserSettings::instance(); + QString configSetting = settings.settingValue ("table-input/extended-config"); + if (configSetting == "true") + { + emit extendedDeleteConfigRequest(getSelectedIds()); + } + else + { + QMetaObject::invokeMethod(mDispatcher, "executeExtendedDelete", Qt::QueuedConnection); + } +} + +void CSVWorld::Table::executeExtendedRevert() +{ + CSMSettings::UserSettings &settings = CSMSettings::UserSettings::instance(); + QString configSetting = settings.settingValue ("table-input/extended-config"); + if (configSetting == "true") + { + emit extendedRevertConfigRequest(getSelectedIds()); + } + else + { + QMetaObject::invokeMethod(mDispatcher, "executeExtendedRevert", Qt::QueuedConnection); + } +} + void CSVWorld::Table::updateUserSetting (const QString &name, const QStringList &list) { if (name=="table-input/jump-to-added") diff --git a/apps/opencs/view/world/table.hpp b/apps/opencs/view/world/table.hpp index 38fcd83bd..7efc3ad34 100644 --- a/apps/opencs/view/world/table.hpp +++ b/apps/opencs/view/world/table.hpp @@ -93,6 +93,8 @@ namespace CSVWorld std::vector getColumnsWithDisplay(CSMWorld::ColumnBase::Display display) const; + std::vector getSelectedIds() const; + virtual std::vector getDraggedRecords() const; signals: @@ -112,6 +114,10 @@ namespace CSVWorld void closeRequest(); + void extendedDeleteConfigRequest(const std::vector &selectedIds); + + void extendedRevertConfigRequest(const std::vector &selectedIds); + private slots: void editCell(); @@ -128,6 +134,10 @@ namespace CSVWorld void previewRecord(); + void executeExtendedDelete(); + + void executeExtendedRevert(); + public slots: void tableSizeUpdate(); diff --git a/apps/opencs/view/world/tablebottombox.cpp b/apps/opencs/view/world/tablebottombox.cpp index eab6b07b3..bfd56b326 100644 --- a/apps/opencs/view/world/tablebottombox.cpp +++ b/apps/opencs/view/world/tablebottombox.cpp @@ -39,9 +39,10 @@ void CSVWorld::TableBottomBox::updateStatus() } } -void CSVWorld::TableBottomBox::extendedConfigRequest(CSVWorld::ExtendedCommandConfigurator::Mode mode) +void CSVWorld::TableBottomBox::extendedConfigRequest(CSVWorld::ExtendedCommandConfigurator::Mode mode, + const std::vector &selectedIds) { - mExtendedConfigurator->configure (mode); + mExtendedConfigurator->configure (mode, selectedIds); mLayout->setCurrentWidget (mExtendedConfigurator); mEditMode = EditMode_ExtendedConfig; setVisible (true); @@ -185,12 +186,12 @@ void CSVWorld::TableBottomBox::cloneRequest(const std::string& id, mCreator->focus(); } -void CSVWorld::TableBottomBox::extendedDeleteConfigRequest() +void CSVWorld::TableBottomBox::extendedDeleteConfigRequest(const std::vector &selectedIds) { - extendedConfigRequest(ExtendedCommandConfigurator::Mode_Delete); + extendedConfigRequest(ExtendedCommandConfigurator::Mode_Delete, selectedIds); } -void CSVWorld::TableBottomBox::extendedRevertConfigRequest() +void CSVWorld::TableBottomBox::extendedRevertConfigRequest(const std::vector &selectedIds) { - extendedConfigRequest(ExtendedCommandConfigurator::Mode_Revert); + extendedConfigRequest(ExtendedCommandConfigurator::Mode_Revert, selectedIds); } diff --git a/apps/opencs/view/world/tablebottombox.hpp b/apps/opencs/view/world/tablebottombox.hpp index d2fb865e7..fded912fe 100644 --- a/apps/opencs/view/world/tablebottombox.hpp +++ b/apps/opencs/view/world/tablebottombox.hpp @@ -45,7 +45,8 @@ namespace CSVWorld void updateStatus(); - void extendedConfigRequest(ExtendedCommandConfigurator::Mode mode); + void extendedConfigRequest(ExtendedCommandConfigurator::Mode mode, + const std::vector &selectedIds); public: @@ -89,8 +90,8 @@ namespace CSVWorld void cloneRequest(const std::string& id, const CSMWorld::UniversalId::Type type); - void extendedDeleteConfigRequest(); - void extendedRevertConfigRequest(); + void extendedDeleteConfigRequest(const std::vector &selectedIds); + void extendedRevertConfigRequest(const std::vector &selectedIds); }; } diff --git a/apps/opencs/view/world/tablesubview.cpp b/apps/opencs/view/world/tablesubview.cpp index 75671a50c..abae6115a 100644 --- a/apps/opencs/view/world/tablesubview.cpp +++ b/apps/opencs/view/world/tablesubview.cpp @@ -71,6 +71,11 @@ CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::D connect (this, SIGNAL(cloneRequest(const std::string&, const CSMWorld::UniversalId::Type)), mBottom, SLOT(cloneRequest(const std::string&, const CSMWorld::UniversalId::Type))); + + connect (mTable, SIGNAL(extendedDeleteConfigRequest(const std::vector &)), + mBottom, SLOT(extendedDeleteConfigRequest(const std::vector &))); + connect (mTable, SIGNAL(extendedRevertConfigRequest(const std::vector &)), + mBottom, SLOT(extendedRevertConfigRequest(const std::vector &))); } connect (mBottom, SIGNAL (requestFocus (const std::string&)), mTable, SLOT (requestFocus (const std::string&))); From 12bf3694bdd5320dcc843a82b75d244e0e9ed975 Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Thu, 2 Jul 2015 22:05:45 +0300 Subject: [PATCH 05/16] Rework widget layout of ExtendedCommandConfigurator --- .../world/extendedcommandconfigurator.cpp | 36 ++++++++----------- .../world/extendedcommandconfigurator.hpp | 4 +-- 2 files changed, 16 insertions(+), 24 deletions(-) diff --git a/apps/opencs/view/world/extendedcommandconfigurator.cpp b/apps/opencs/view/world/extendedcommandconfigurator.cpp index 6ba26634b..9f067545c 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.cpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.cpp @@ -3,6 +3,7 @@ #include #include #include +#include #include #include "../../model/world/commanddispatcher.hpp" @@ -39,10 +40,8 @@ CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Docum mCancelButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); connect(mCancelButton, SIGNAL(clicked(bool)), this, SIGNAL(done())); - mButtonLayout = new QHBoxLayout(); - mButtonLayout->setAlignment(Qt::AlignCenter); - mButtonLayout->addWidget(mPerformButton); - mButtonLayout->addWidget(mCancelButton); + mCommandTitle = new QLabel(this); + mCommandTitle->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); mTypeGroup = new QGroupBox(this); @@ -50,15 +49,12 @@ CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Docum groupLayout->setAlignment(Qt::AlignCenter); mTypeGroup->setLayout(groupLayout); - QVBoxLayout *mainLayout = new QVBoxLayout(this); + QHBoxLayout *mainLayout = new QHBoxLayout(this); mainLayout->setSizeConstraint(QLayout::SetNoConstraint); + mainLayout->addWidget(mCommandTitle); mainLayout->addWidget(mTypeGroup); - mainLayout->addLayout(mButtonLayout); -} - -CSVWorld::ExtendedCommandConfigurator::~ExtendedCommandConfigurator() -{ - delete mButtonLayout; + mainLayout->addWidget(mPerformButton); + mainLayout->addWidget(mCancelButton); } void CSVWorld::ExtendedCommandConfigurator::configure(CSVWorld::ExtendedCommandConfigurator::Mode mode, @@ -67,7 +63,9 @@ void CSVWorld::ExtendedCommandConfigurator::configure(CSVWorld::ExtendedCommandC mMode = mode; if (mMode != Mode_None) { - mTypeGroup->setTitle(getTypeGroupTitle(mMode)); + QString title = (mMode == Mode_Delete) ? "Extended Delete" : "Extended Revert"; + title.append(" from:"); + mCommandTitle->setText(title); mCommandDispatcher->setSelection(selectedIds); setupCheckBoxes(mCommandDispatcher->getExtendedTypes()); setupGroupLayout(); @@ -90,12 +88,6 @@ void CSVWorld::ExtendedCommandConfigurator::setupGroupLayout() int groupWidth = mTypeGroup->geometry().width(); QGridLayout *layout = qobject_cast(mTypeGroup->layout()); - // One row of checkboxes with enough space - the setup is over - if (mNumUsedCheckBoxes > 0 && layout->rowCount() == 1 && groupWidth >= mTypeGroup->sizeHint().width()) - { - return; - } - // Find the optimal number of rows to place the checkboxes within the available space int divider = 1; do @@ -111,7 +103,7 @@ void CSVWorld::ExtendedCommandConfigurator::setupGroupLayout() CheckBoxMap::const_iterator end = mTypeCheckBoxes.end(); for (; current != end; ++current) { - if (current->first->isVisible()) + if (counter < mNumUsedCheckBoxes) { int row = counter / itemsPerRow; int column = counter - (counter / itemsPerRow) * itemsPerRow; @@ -121,7 +113,7 @@ void CSVWorld::ExtendedCommandConfigurator::setupGroupLayout() } divider *= 2; } - while (groupWidth < mTypeGroup->sizeHint().width()); + while (groupWidth < mTypeGroup->sizeHint().width() && divider <= mNumUsedCheckBoxes); } void CSVWorld::ExtendedCommandConfigurator::setupCheckBoxes(const std::vector &types) @@ -133,7 +125,7 @@ void CSVWorld::ExtendedCommandConfigurator::setupCheckBoxes(const std::vector 0; --i) { - mTypeCheckBoxes.insert(std::make_pair(new QCheckBox(this), CSMWorld::UniversalId::Type_None)); + mTypeCheckBoxes.insert(std::make_pair(new QCheckBox(mTypeGroup), CSMWorld::UniversalId::Type_None)); } } @@ -156,7 +148,7 @@ void CSVWorld::ExtendedCommandConfigurator::setupCheckBoxes(const std::vectorfirst->hide(); } } - mNumUsedCheckBoxes = counter - 1; + mNumUsedCheckBoxes = numTypes; } void CSVWorld::ExtendedCommandConfigurator::performExtendedCommand() diff --git a/apps/opencs/view/world/extendedcommandconfigurator.hpp b/apps/opencs/view/world/extendedcommandconfigurator.hpp index dd2477444..8efe36fa7 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.hpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.hpp @@ -8,6 +8,7 @@ class QPushButton; class QGroupBox; class QCheckBox; +class QLabel; class QHBoxLayout; namespace CSMDoc @@ -35,7 +36,7 @@ namespace CSVWorld QPushButton *mPerformButton; QPushButton *mCancelButton; - QHBoxLayout *mButtonLayout; + QLabel *mCommandTitle; QGroupBox *mTypeGroup; CheckBoxMap mTypeCheckBoxes; int mNumUsedCheckBoxes; @@ -50,7 +51,6 @@ namespace CSVWorld ExtendedCommandConfigurator(CSMDoc::Document &document, const CSMWorld::UniversalId &id, QWidget *parent = 0); - virtual ~ExtendedCommandConfigurator(); void configure(Mode mode, const std::vector &selectedIds); From 260f6f22aecfa6722e103620ed657c33549de597 Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Fri, 3 Jul 2015 22:07:37 +0300 Subject: [PATCH 06/16] TableBottomBox adjusts its size according to the current widget size --- apps/opencs/view/world/tablebottombox.cpp | 22 ++++++++++++++++++++++ apps/opencs/view/world/tablebottombox.hpp | 4 ++++ 2 files changed, 26 insertions(+) diff --git a/apps/opencs/view/world/tablebottombox.cpp b/apps/opencs/view/world/tablebottombox.cpp index bfd56b326..eee25b1bf 100644 --- a/apps/opencs/view/world/tablebottombox.cpp +++ b/apps/opencs/view/world/tablebottombox.cpp @@ -9,6 +9,20 @@ #include "creator.hpp" +void CSVWorld::TableBottomBox::updateSize() +{ + // Make sure that the size of the bottom box is determined by the currently visible widget + for (int i = 0; i < mLayout->count(); ++i) + { + QSizePolicy::Policy verPolicy = QSizePolicy::Ignored; + if (mLayout->widget(i) == mLayout->currentWidget()) + { + verPolicy = QSizePolicy::Expanding; + } + mLayout->widget(i)->setSizePolicy(QSizePolicy::Expanding, verPolicy); + } +} + void CSVWorld::TableBottomBox::updateStatus() { if (mShowStatusBar) @@ -61,6 +75,7 @@ CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFacto mLayout = new QStackedLayout; mLayout->setContentsMargins (0, 0, 0, 0); + connect (mLayout, SIGNAL (currentChanged (int)), this, SLOT (currentWidgetChanged (int))); mStatus = new QLabel; @@ -87,6 +102,8 @@ CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFacto mExtendedConfigurator = new ExtendedCommandConfigurator (document, id, this); mLayout->addWidget (mExtendedConfigurator); connect (mExtendedConfigurator, SIGNAL (done()), this, SLOT (requestDone())); + + updateSize(); } void CSVWorld::TableBottomBox::setEditLock (bool locked) @@ -129,6 +146,11 @@ void CSVWorld::TableBottomBox::requestDone() mEditMode = EditMode_None; } +void CSVWorld::TableBottomBox::currentWidgetChanged(int /*index*/) +{ + updateSize(); +} + void CSVWorld::TableBottomBox::selectionSizeChanged (int size) { if (mStatusCount[3]!=size) diff --git a/apps/opencs/view/world/tablebottombox.hpp b/apps/opencs/view/world/tablebottombox.hpp index fded912fe..15ae2924c 100644 --- a/apps/opencs/view/world/tablebottombox.hpp +++ b/apps/opencs/view/world/tablebottombox.hpp @@ -43,6 +43,8 @@ namespace CSVWorld TableBottomBox (const TableBottomBox&); TableBottomBox& operator= (const TableBottomBox&); + void updateSize(); + void updateStatus(); void extendedConfigRequest(ExtendedCommandConfigurator::Mode mode, @@ -77,6 +79,8 @@ namespace CSVWorld void requestDone(); ///< \note This slot being called does not imply success. + void currentWidgetChanged(int index); + public slots: void selectionSizeChanged (int size); From 95d16b24c05142943b22c31162bebc1b7b46a82f Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Fri, 3 Jul 2015 22:25:56 +0300 Subject: [PATCH 07/16] ExtendedCommandConfigurator: disable the perform button when all tables are unchecked --- .../world/extendedcommandconfigurator.cpp | 24 +++++++++++++++++-- .../world/extendedcommandconfigurator.hpp | 2 ++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/world/extendedcommandconfigurator.cpp b/apps/opencs/view/world/extendedcommandconfigurator.cpp index 9f067545c..257e9c4f0 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.cpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.cpp @@ -28,6 +28,7 @@ CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Docum QWidget *parent) : QWidget(parent), mNumUsedCheckBoxes(0), + mNumChecked(0), mMode(Mode_None) { mCommandDispatcher = new CSMWorld::CommandDispatcher(document, id, this); @@ -125,7 +126,9 @@ void CSVWorld::ExtendedCommandConfigurator::setupCheckBoxes(const std::vector 0; --i) { - mTypeCheckBoxes.insert(std::make_pair(new QCheckBox(mTypeGroup), CSMWorld::UniversalId::Type_None)); + QCheckBox *checkBox = new QCheckBox(mTypeGroup); + connect(checkBox, SIGNAL(stateChanged(int)), this, SLOT(checkBoxStateChanged(int))); + mTypeCheckBoxes.insert(std::make_pair(checkBox, CSMWorld::UniversalId::Type_None)); } } @@ -148,7 +151,7 @@ void CSVWorld::ExtendedCommandConfigurator::setupCheckBoxes(const std::vectorfirst->hide(); } } - mNumUsedCheckBoxes = numTypes; + mNumChecked = mNumUsedCheckBoxes = numTypes; } void CSVWorld::ExtendedCommandConfigurator::performExtendedCommand() @@ -176,3 +179,20 @@ void CSVWorld::ExtendedCommandConfigurator::performExtendedCommand() } emit done(); } + +void CSVWorld::ExtendedCommandConfigurator::checkBoxStateChanged(int state) +{ + switch (state) + { + case Qt::Unchecked: + --mNumChecked; + break; + case Qt::Checked: + ++mNumChecked; + break; + case Qt::PartiallyChecked: // Not used + break; + } + + mPerformButton->setEnabled(mNumChecked > 0); +} diff --git a/apps/opencs/view/world/extendedcommandconfigurator.hpp b/apps/opencs/view/world/extendedcommandconfigurator.hpp index 8efe36fa7..6a5e1e2e7 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.hpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.hpp @@ -40,6 +40,7 @@ namespace CSVWorld QGroupBox *mTypeGroup; CheckBoxMap mTypeCheckBoxes; int mNumUsedCheckBoxes; + int mNumChecked; Mode mMode; CSMWorld::CommandDispatcher *mCommandDispatcher; @@ -59,6 +60,7 @@ namespace CSVWorld private slots: void performExtendedCommand(); + void checkBoxStateChanged(int state); signals: void done(); From 05cc130212162195f2f09143000f1fb49d38442f Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Fri, 3 Jul 2015 22:31:38 +0300 Subject: [PATCH 08/16] The configuration panel gets a focus when opening --- apps/opencs/view/world/tablebottombox.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/opencs/view/world/tablebottombox.cpp b/apps/opencs/view/world/tablebottombox.cpp index eee25b1bf..3a7fa8e8a 100644 --- a/apps/opencs/view/world/tablebottombox.cpp +++ b/apps/opencs/view/world/tablebottombox.cpp @@ -60,6 +60,7 @@ void CSVWorld::TableBottomBox::extendedConfigRequest(CSVWorld::ExtendedCommandCo mLayout->setCurrentWidget (mExtendedConfigurator); mEditMode = EditMode_ExtendedConfig; setVisible (true); + mExtendedConfigurator->setFocus(); } CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFactory, From e664ef75785929d5657986bd2cacace7779c627b Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Fri, 3 Jul 2015 23:15:26 +0300 Subject: [PATCH 09/16] ExtendedCommandConfigurator: the perform button takes the name of the command that is executed --- .../world/extendedcommandconfigurator.cpp | 24 ++----------------- .../world/extendedcommandconfigurator.hpp | 1 - 2 files changed, 2 insertions(+), 23 deletions(-) diff --git a/apps/opencs/view/world/extendedcommandconfigurator.cpp b/apps/opencs/view/world/extendedcommandconfigurator.cpp index 257e9c4f0..36bff7d59 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.cpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.cpp @@ -9,20 +9,6 @@ #include "../../model/world/commanddispatcher.hpp" #include "../../model/world/universalid.hpp" -namespace -{ - QString getTypeGroupTitle(CSVWorld::ExtendedCommandConfigurator::Mode mode) - { - static const QString title = "Tables affected by "; - QString titleSuffix = "Extended Delete"; - if (mode == CSVWorld::ExtendedCommandConfigurator::Mode_Revert) - { - titleSuffix = "Extended Revert"; - } - return title + titleSuffix; - } -} - CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Document &document, const CSMWorld::UniversalId &id, QWidget *parent) @@ -33,7 +19,7 @@ CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Docum { mCommandDispatcher = new CSMWorld::CommandDispatcher(document, id, this); - mPerformButton = new QPushButton("Perform", this); + mPerformButton = new QPushButton(this); mPerformButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); connect(mPerformButton, SIGNAL(clicked(bool)), this, SLOT(performExtendedCommand())); @@ -41,9 +27,6 @@ CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Docum mCancelButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); connect(mCancelButton, SIGNAL(clicked(bool)), this, SIGNAL(done())); - mCommandTitle = new QLabel(this); - mCommandTitle->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); - mTypeGroup = new QGroupBox(this); QGridLayout *groupLayout = new QGridLayout(mTypeGroup); @@ -52,7 +35,6 @@ CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Docum QHBoxLayout *mainLayout = new QHBoxLayout(this); mainLayout->setSizeConstraint(QLayout::SetNoConstraint); - mainLayout->addWidget(mCommandTitle); mainLayout->addWidget(mTypeGroup); mainLayout->addWidget(mPerformButton); mainLayout->addWidget(mCancelButton); @@ -64,9 +46,7 @@ void CSVWorld::ExtendedCommandConfigurator::configure(CSVWorld::ExtendedCommandC mMode = mode; if (mMode != Mode_None) { - QString title = (mMode == Mode_Delete) ? "Extended Delete" : "Extended Revert"; - title.append(" from:"); - mCommandTitle->setText(title); + mPerformButton->setText((mMode == Mode_Delete) ? "Extended Delete" : "Extended Revert"); mCommandDispatcher->setSelection(selectedIds); setupCheckBoxes(mCommandDispatcher->getExtendedTypes()); setupGroupLayout(); diff --git a/apps/opencs/view/world/extendedcommandconfigurator.hpp b/apps/opencs/view/world/extendedcommandconfigurator.hpp index 6a5e1e2e7..9ed16aa1e 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.hpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.hpp @@ -36,7 +36,6 @@ namespace CSVWorld QPushButton *mPerformButton; QPushButton *mCancelButton; - QLabel *mCommandTitle; QGroupBox *mTypeGroup; CheckBoxMap mTypeCheckBoxes; int mNumUsedCheckBoxes; From ff3c9a6fb28bcddfdc73da2b0a3eaa23e8ffd0b0 Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Fri, 3 Jul 2015 23:35:00 +0300 Subject: [PATCH 10/16] ExtendedCommandConfigurator: the perform button is now the default for the widget --- apps/opencs/view/world/extendedcommandconfigurator.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/opencs/view/world/extendedcommandconfigurator.cpp b/apps/opencs/view/world/extendedcommandconfigurator.cpp index 36bff7d59..85c5a2bda 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.cpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.cpp @@ -20,6 +20,7 @@ CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Docum mCommandDispatcher = new CSMWorld::CommandDispatcher(document, id, this); mPerformButton = new QPushButton(this); + mPerformButton->setDefault(true); mPerformButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); connect(mPerformButton, SIGNAL(clicked(bool)), this, SLOT(performExtendedCommand())); From 1f826476ff6fc3627c9968cc78912d3dde087b1b Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Sat, 4 Jul 2015 02:02:22 +0300 Subject: [PATCH 11/16] Fix build error --- apps/opencs/view/world/extendedcommandconfigurator.cpp | 1 - apps/opencs/view/world/extendedcommandconfigurator.hpp | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/world/extendedcommandconfigurator.cpp b/apps/opencs/view/world/extendedcommandconfigurator.cpp index 85c5a2bda..d3b97b127 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.cpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.cpp @@ -7,7 +7,6 @@ #include #include "../../model/world/commanddispatcher.hpp" -#include "../../model/world/universalid.hpp" CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Document &document, const CSMWorld::UniversalId &id, diff --git a/apps/opencs/view/world/extendedcommandconfigurator.hpp b/apps/opencs/view/world/extendedcommandconfigurator.hpp index 9ed16aa1e..590cabab1 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.hpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.hpp @@ -5,6 +5,8 @@ #include +#include "../../model/world/universalid.hpp" + class QPushButton; class QGroupBox; class QCheckBox; @@ -19,7 +21,6 @@ namespace CSMDoc namespace CSMWorld { class CommandDispatcher; - class UniversalId; } namespace CSVWorld From 880bc31ddf0bb287aff8252e9b04eb17d26236b4 Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Sat, 4 Jul 2015 20:30:02 +0300 Subject: [PATCH 12/16] TableBottomBox: Creator/Configurator can be closed via Escape --- apps/opencs/view/world/tablebottombox.cpp | 18 ++++++++++++++++++ apps/opencs/view/world/tablebottombox.hpp | 2 ++ 2 files changed, 20 insertions(+) diff --git a/apps/opencs/view/world/tablebottombox.cpp b/apps/opencs/view/world/tablebottombox.cpp index 3a7fa8e8a..d02b76fdc 100644 --- a/apps/opencs/view/world/tablebottombox.cpp +++ b/apps/opencs/view/world/tablebottombox.cpp @@ -6,6 +6,8 @@ #include #include #include +#include +#include #include "creator.hpp" @@ -92,6 +94,7 @@ CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFacto if (mCreator) { + mCreator->installEventFilter(this); mLayout->addWidget (mCreator); connect (mCreator, SIGNAL (done()), this, SLOT (requestDone())); @@ -101,6 +104,7 @@ CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFacto } mExtendedConfigurator = new ExtendedCommandConfigurator (document, id, this); + mExtendedConfigurator->installEventFilter(this); mLayout->addWidget (mExtendedConfigurator); connect (mExtendedConfigurator, SIGNAL (done()), this, SLOT (requestDone())); @@ -118,6 +122,20 @@ CSVWorld::TableBottomBox::~TableBottomBox() delete mCreator; } +bool CSVWorld::TableBottomBox::eventFilter(QObject *object, QEvent *event) +{ + if (event->type() == QEvent::KeyPress) + { + QKeyEvent *keyEvent = static_cast(event); + if (keyEvent->key() == Qt::Key_Escape) + { + requestDone(); + return true; + } + } + return QWidget::eventFilter(object, event); +} + void CSVWorld::TableBottomBox::setStatusBar (bool show) { if (show!=mShowStatusBar) diff --git a/apps/opencs/view/world/tablebottombox.hpp b/apps/opencs/view/world/tablebottombox.hpp index 15ae2924c..a24844890 100644 --- a/apps/opencs/view/world/tablebottombox.hpp +++ b/apps/opencs/view/world/tablebottombox.hpp @@ -59,6 +59,8 @@ namespace CSVWorld virtual ~TableBottomBox(); + virtual bool eventFilter(QObject *object, QEvent *event); + void setEditLock (bool locked); void setStatusBar (bool show); From 4fbd24206b49e4dd981caaae47d3f39b62edeb97 Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Sat, 4 Jul 2015 20:47:10 +0300 Subject: [PATCH 13/16] ExtendedCommandConfigurator: layout changes --- apps/opencs/view/world/extendedcommandconfigurator.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/world/extendedcommandconfigurator.cpp b/apps/opencs/view/world/extendedcommandconfigurator.cpp index d3b97b127..b9b2fa10c 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.cpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.cpp @@ -30,11 +30,12 @@ CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Docum mTypeGroup = new QGroupBox(this); QGridLayout *groupLayout = new QGridLayout(mTypeGroup); - groupLayout->setAlignment(Qt::AlignCenter); + groupLayout->setAlignment(Qt::AlignLeft | Qt::AlignVCenter); mTypeGroup->setLayout(groupLayout); QHBoxLayout *mainLayout = new QHBoxLayout(this); mainLayout->setSizeConstraint(QLayout::SetNoConstraint); + mainLayout->setContentsMargins(0, 0, 0, 0); mainLayout->addWidget(mTypeGroup); mainLayout->addWidget(mPerformButton); mainLayout->addWidget(mCancelButton); From ceb3dea55cc70d3518d1253b00ff45ecc21ffc5f Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Sun, 5 Jul 2015 20:11:21 +0300 Subject: [PATCH 14/16] Rewording of the user setting for extended configuration --- apps/opencs/model/settings/usersettings.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index cb001fea9..05b06d562 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -217,10 +217,13 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() jumpToAdded->setDeclaredValues (jumpValues); Setting *extendedConfig = createSetting (Type_CheckBox, "extended-config", - "Enable configuration of the extended delete/revert"); + "Manually specify affected record types for an extended delete/revert"); extendedConfig->setDefaultValue("false"); - extendedConfig->setToolTip("Enables the ability to specify tables that will be affected by " - "the extended delete/revert command"); + extendedConfig->setToolTip("Delete and revert commands have an extended form that also affects " + "associated records.\n\n" + "If this option is enabled, types of affected records are selected " + "manually before a command execution.\nOtherwise, all associated " + "records are deleted/reverted immediately."); } declareSection ("report-input", "Report Input"); From 3c6bc7406219e1fec46fe79fa9fde76a7dc999c5 Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Sun, 5 Jul 2015 22:10:37 +0300 Subject: [PATCH 15/16] Close the extended configurator when all respective records were removed outside --- .../world/extendedcommandconfigurator.cpp | 40 ++++++++++++++++++- .../world/extendedcommandconfigurator.hpp | 4 ++ 2 files changed, 42 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/world/extendedcommandconfigurator.cpp b/apps/opencs/view/world/extendedcommandconfigurator.cpp index b9b2fa10c..d243ff256 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.cpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.cpp @@ -1,12 +1,17 @@ #include "extendedcommandconfigurator.hpp" +#include + #include #include #include #include #include +#include "../../model/doc/document.hpp" + #include "../../model/world/commanddispatcher.hpp" +#include "../../model/world/data.hpp" CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Document &document, const CSMWorld::UniversalId &id, @@ -14,10 +19,13 @@ CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Docum : QWidget(parent), mNumUsedCheckBoxes(0), mNumChecked(0), - mMode(Mode_None) + mMode(Mode_None), + mData(document.getData()) { mCommandDispatcher = new CSMWorld::CommandDispatcher(document, id, this); + connect(&mData, SIGNAL(idListChanged()), this, SLOT(dataIdListChanged())); + mPerformButton = new QPushButton(this); mPerformButton->setDefault(true); mPerformButton->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); @@ -48,7 +56,8 @@ void CSVWorld::ExtendedCommandConfigurator::configure(CSVWorld::ExtendedCommandC if (mMode != Mode_None) { mPerformButton->setText((mMode == Mode_Delete) ? "Extended Delete" : "Extended Revert"); - mCommandDispatcher->setSelection(selectedIds); + mSelectedIds = selectedIds; + mCommandDispatcher->setSelection(mSelectedIds); setupCheckBoxes(mCommandDispatcher->getExtendedTypes()); setupGroupLayout(); } @@ -177,3 +186,30 @@ void CSVWorld::ExtendedCommandConfigurator::checkBoxStateChanged(int state) mPerformButton->setEnabled(mNumChecked > 0); } + +void CSVWorld::ExtendedCommandConfigurator::dataIdListChanged() +{ + bool idsRemoved = false; + for (int i = 0; i < static_cast(mSelectedIds.size()); ++i) + { + if (!mData.hasId(mSelectedIds[i])) + { + std::swap(mSelectedIds[i], mSelectedIds.back()); + mSelectedIds.pop_back(); + idsRemoved = true; + --i; + } + } + + // If all selected IDs were removed, cancel the configurator + if (mSelectedIds.empty()) + { + emit done(); + return; + } + + if (idsRemoved) + { + mCommandDispatcher->setSelection(mSelectedIds); + } +} diff --git a/apps/opencs/view/world/extendedcommandconfigurator.hpp b/apps/opencs/view/world/extendedcommandconfigurator.hpp index 590cabab1..2e06e9c9c 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.hpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.hpp @@ -21,6 +21,7 @@ namespace CSMDoc namespace CSMWorld { class CommandDispatcher; + class Data; } namespace CSVWorld @@ -44,6 +45,8 @@ namespace CSVWorld Mode mMode; CSMWorld::CommandDispatcher *mCommandDispatcher; + CSMWorld::Data &mData; + std::vector mSelectedIds; void setupGroupLayout(); void setupCheckBoxes(const std::vector &types); @@ -61,6 +64,7 @@ namespace CSVWorld private slots: void performExtendedCommand(); void checkBoxStateChanged(int state); + void dataIdListChanged(); signals: void done(); From 47d21ff4b34c1192746ba7533d6c0815e7afc194 Mon Sep 17 00:00:00 2001 From: Stanislav Bas Date: Sun, 5 Jul 2015 22:49:48 +0300 Subject: [PATCH 16/16] Add edit locking to ExtendedCommandConfigurator --- .../world/extendedcommandconfigurator.cpp | 26 ++++++++++++++++++- .../world/extendedcommandconfigurator.hpp | 4 +++ apps/opencs/view/world/tablebottombox.cpp | 1 + 3 files changed, 30 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/world/extendedcommandconfigurator.cpp b/apps/opencs/view/world/extendedcommandconfigurator.cpp index d243ff256..2cf6222a6 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.cpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.cpp @@ -20,7 +20,8 @@ CSVWorld::ExtendedCommandConfigurator::ExtendedCommandConfigurator(CSMDoc::Docum mNumUsedCheckBoxes(0), mNumChecked(0), mMode(Mode_None), - mData(document.getData()) + mData(document.getData()), + mEditLock(false) { mCommandDispatcher = new CSMWorld::CommandDispatcher(document, id, this); @@ -58,8 +59,19 @@ void CSVWorld::ExtendedCommandConfigurator::configure(CSVWorld::ExtendedCommandC mPerformButton->setText((mMode == Mode_Delete) ? "Extended Delete" : "Extended Revert"); mSelectedIds = selectedIds; mCommandDispatcher->setSelection(mSelectedIds); + setupCheckBoxes(mCommandDispatcher->getExtendedTypes()); setupGroupLayout(); + lockWidgets(mEditLock); + } +} + +void CSVWorld::ExtendedCommandConfigurator::setEditLock(bool locked) +{ + if (mEditLock != locked) + { + mEditLock = locked; + lockWidgets(mEditLock); } } @@ -144,6 +156,18 @@ void CSVWorld::ExtendedCommandConfigurator::setupCheckBoxes(const std::vectorsetEnabled(!mEditLock && mNumChecked > 0); + + CheckBoxMap::const_iterator current = mTypeCheckBoxes.begin(); + CheckBoxMap::const_iterator end = mTypeCheckBoxes.end(); + for (int i = 0; current != end && i < mNumUsedCheckBoxes; ++current, ++i) + { + current->first->setEnabled(!mEditLock); + } +} + void CSVWorld::ExtendedCommandConfigurator::performExtendedCommand() { std::vector types; diff --git a/apps/opencs/view/world/extendedcommandconfigurator.hpp b/apps/opencs/view/world/extendedcommandconfigurator.hpp index 2e06e9c9c..641b4a524 100644 --- a/apps/opencs/view/world/extendedcommandconfigurator.hpp +++ b/apps/opencs/view/world/extendedcommandconfigurator.hpp @@ -48,8 +48,11 @@ namespace CSVWorld CSMWorld::Data &mData; std::vector mSelectedIds; + bool mEditLock; + void setupGroupLayout(); void setupCheckBoxes(const std::vector &types); + void lockWidgets(bool locked); public: ExtendedCommandConfigurator(CSMDoc::Document &document, @@ -57,6 +60,7 @@ namespace CSVWorld QWidget *parent = 0); void configure(Mode mode, const std::vector &selectedIds); + void setEditLock(bool locked); protected: virtual void resizeEvent(QResizeEvent *event); diff --git a/apps/opencs/view/world/tablebottombox.cpp b/apps/opencs/view/world/tablebottombox.cpp index d02b76fdc..225ff32a4 100644 --- a/apps/opencs/view/world/tablebottombox.cpp +++ b/apps/opencs/view/world/tablebottombox.cpp @@ -115,6 +115,7 @@ void CSVWorld::TableBottomBox::setEditLock (bool locked) { if (mCreator) mCreator->setEditLock (locked); + mExtendedConfigurator->setEditLock (locked); } CSVWorld::TableBottomBox::~TableBottomBox()