From 502cc852da0f10dae95ba10ec363a2be66707304 Mon Sep 17 00:00:00 2001 From: scrawl Date: Fri, 26 Jun 2015 20:16:32 +0200 Subject: [PATCH 01/10] Handle encoding conversions when saving TES3 header (Fixes #2727) --- components/esm/esmwriter.cpp | 9 +++++++++ components/esm/esmwriter.hpp | 1 + components/esm/loadtes3.cpp | 8 +++++++- 3 files changed, 17 insertions(+), 1 deletion(-) diff --git a/components/esm/esmwriter.cpp b/components/esm/esmwriter.cpp index c64678e70..4d9999143 100644 --- a/components/esm/esmwriter.cpp +++ b/components/esm/esmwriter.cpp @@ -174,6 +174,15 @@ namespace ESM endRecord(name); } + void ESMWriter::writeFixedSizeString(const std::string &data, int size) + { + std::string string; + if (!data.empty()) + string = mEncoder ? mEncoder->getLegacyEnc(data) : data; + string.resize(size); + write(string.c_str(), string.size()); + } + void ESMWriter::writeHString(const std::string& data) { if (data.size() == 0) diff --git a/components/esm/esmwriter.hpp b/components/esm/esmwriter.hpp index 30cec58b4..d11b3c940 100644 --- a/components/esm/esmwriter.hpp +++ b/components/esm/esmwriter.hpp @@ -120,6 +120,7 @@ public: void startSubRecord(const std::string& name); void endRecord(const std::string& name); void endRecord(uint32_t name); + void writeFixedSizeString(const std::string& data, int size); void writeHString(const std::string& data); void writeHCString(const std::string& data); void writeName(const std::string& data); diff --git a/components/esm/loadtes3.cpp b/components/esm/loadtes3.cpp index 9c0c55b8f..7d749c4d9 100644 --- a/components/esm/loadtes3.cpp +++ b/components/esm/loadtes3.cpp @@ -71,7 +71,13 @@ void ESM::Header::save (ESMWriter &esm) if (mFormat>0) esm.writeHNT ("FORM", mFormat); - esm.writeHNT ("HEDR", mData, 300); + esm.startSubRecord("HEDR"); + esm.writeT(mData.version); + esm.writeT(mData.type); + esm.writeFixedSizeString(mData.author.toString(), 32); + esm.writeFixedSizeString(mData.desc.toString(), 256); + esm.writeT(mData.records); + esm.endRecord("HEDR"); for (std::vector::iterator iter = mMaster.begin(); iter != mMaster.end(); ++iter) From 49dc30683f1e0d9366ab3afa65419e8f9d14c57d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 27 Jun 2015 12:49:56 +0200 Subject: [PATCH 02/10] refactored dialogue subview button bar into a new class --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/world/dialoguesubview.cpp | 72 +++------------ apps/opencs/view/world/recordbuttonbar.cpp | 100 +++++++++++++++++++++ apps/opencs/view/world/recordbuttonbar.hpp | 54 +++++++++++ 4 files changed, 165 insertions(+), 63 deletions(-) create mode 100644 apps/opencs/view/world/recordbuttonbar.cpp create mode 100644 apps/opencs/view/world/recordbuttonbar.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 3399b9ddd..0607f67ee 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 + dialoguespinbox recordbuttonbar ) opencs_units_noqt (view/world diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 99650834e..a2f25df44 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -40,6 +40,7 @@ #include "util.hpp" #include "tablebottombox.hpp" #include "nestedtable.hpp" +#include "recordbuttonbar.hpp" /* ==============================NotEditableSubDelegate========================================== */ @@ -712,69 +713,16 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, connect(mBottom, SIGNAL(requestFocus(const std::string&)), this, SLOT(requestFocus(const std::string&))); // buttons - QHBoxLayout *buttonsLayout = new QHBoxLayout; - QToolButton* prevButton = new QToolButton (this); - prevButton->setIcon(QIcon(":/go-previous.png")); - prevButton->setToolTip ("Switch to previous record"); - QToolButton* nextButton = new QToolButton (this); - nextButton->setIcon(QIcon(":/go-next.png")); - nextButton->setToolTip ("Switch to next record"); - buttonsLayout->addWidget(prevButton, 0); - buttonsLayout->addWidget(nextButton, 1); - buttonsLayout->addStretch(2); + RecordButtonBar *buttons = new RecordButtonBar (getTable(), mBottom, + &getCommandDispatcher(), this); + + getMainLayout().addWidget (buttons); - QToolButton* cloneButton = new QToolButton (this); - cloneButton->setIcon(QIcon(":/edit-clone.png")); - cloneButton->setToolTip ("Clone record"); - QToolButton* addButton = new QToolButton (this); - addButton->setIcon(QIcon(":/add.png")); - addButton->setToolTip ("Add new record"); - QToolButton* deleteButton = new QToolButton (this); - deleteButton->setIcon(QIcon(":/edit-delete.png")); - deleteButton->setToolTip ("Delete record"); - QToolButton* revertButton = new QToolButton (this); - revertButton->setIcon(QIcon(":/edit-undo.png")); - revertButton->setToolTip ("Revert record"); - - if (getTable().getFeatures() & CSMWorld::IdTable::Feature_Preview) - { - QToolButton* previewButton = new QToolButton (this); - previewButton->setIcon(QIcon(":/edit-preview.png")); - previewButton->setToolTip ("Open a preview of this record"); - buttonsLayout->addWidget(previewButton); - connect(previewButton, SIGNAL(clicked()), this, SLOT(showPreview())); - } - - if (getTable().getFeatures() & CSMWorld::IdTable::Feature_View) - { - QToolButton* viewButton = new QToolButton (this); - viewButton->setIcon(QIcon(":/cell.png")); - viewButton->setToolTip ("Open a scene view of the cell this record is located in"); - buttonsLayout->addWidget(viewButton); - connect(viewButton, SIGNAL(clicked()), this, SLOT(viewRecord())); - } - - buttonsLayout->addWidget(cloneButton); - buttonsLayout->addWidget(addButton); - buttonsLayout->addWidget(deleteButton); - buttonsLayout->addWidget(revertButton); - - connect(nextButton, SIGNAL(clicked()), this, SLOT(nextId())); - connect(prevButton, SIGNAL(clicked()), this, SLOT(prevId())); - connect(cloneButton, SIGNAL(clicked()), this, SLOT(cloneRequest())); - connect(revertButton, SIGNAL(clicked()), &getCommandDispatcher(), SLOT(executeRevert())); - connect(deleteButton, SIGNAL(clicked()), &getCommandDispatcher(), SLOT(executeDelete())); - - connect(addButton, SIGNAL(clicked()), mBottom, SLOT(createRequest())); - - if(!mBottom->canCreateAndDelete()) - { - cloneButton->setDisabled (true); - addButton->setDisabled (true); - deleteButton->setDisabled (true); - } - - getMainLayout().addLayout (buttonsLayout); + connect (buttons, SIGNAL(nextId()), this, SLOT(nextId())); + connect (buttons, SIGNAL (prevId()), this, SLOT(prevId())); + connect (buttons, SIGNAL (cloneRequest()), this, SLOT(cloneRequest())); + connect (buttons, SIGNAL (showPreview()), this, SLOT(showPreview())); + connect (buttons, SIGNAL (viewRecord()), this, SLOT(viewRecord())); } void CSVWorld::DialogueSubView::cloneRequest() diff --git a/apps/opencs/view/world/recordbuttonbar.cpp b/apps/opencs/view/world/recordbuttonbar.cpp new file mode 100644 index 000000000..2f5395317 --- /dev/null +++ b/apps/opencs/view/world/recordbuttonbar.cpp @@ -0,0 +1,100 @@ + +#include "recordbuttonbar.hpp" + +#include +#include + +#include "../../model/world/idtable.hpp" +#include "../../model/world/commanddispatcher.hpp" + +#include "../world/tablebottombox.hpp" + +CSVWorld::RecordButtonBar::RecordButtonBar (CSMWorld::IdTable& table, TableBottomBox *bottomBox, + CSMWorld::CommandDispatcher *commandDispatcher, QWidget *parent) +: QWidget (parent), mTable (table), mBottom (bottomBox), mCommandDispatcher (commandDispatcher) +{ + QHBoxLayout *buttonsLayout = new QHBoxLayout; + buttonsLayout->setContentsMargins (0, 0, 0, 0); + + // left section + QToolButton* prevButton = new QToolButton (this); + prevButton->setIcon(QIcon(":/go-previous.png")); + prevButton->setToolTip ("Switch to previous record"); + buttonsLayout->addWidget (prevButton, 0); + + QToolButton* nextButton = new QToolButton (this); + nextButton->setIcon(QIcon(":/go-next.png")); + nextButton->setToolTip ("Switch to next record"); + buttonsLayout->addWidget (nextButton, 1); + + buttonsLayout->addStretch(2); + + // optional buttons of the right section + if (mTable.getFeatures() & CSMWorld::IdTable::Feature_Preview) + { + QToolButton* previewButton = new QToolButton (this); + previewButton->setIcon(QIcon(":/edit-preview.png")); + previewButton->setToolTip ("Open a preview of this record"); + buttonsLayout->addWidget(previewButton); + connect (previewButton, SIGNAL(clicked()), this, SIGNAL (showPreview())); + } + + if (mTable.getFeatures() & CSMWorld::IdTable::Feature_View) + { + QToolButton* viewButton = new QToolButton (this); + viewButton->setIcon(QIcon(":/cell.png")); + viewButton->setToolTip ("Open a scene view of the cell this record is located in"); + buttonsLayout->addWidget(viewButton); + connect (viewButton, SIGNAL(clicked()), this, SIGNAL (viewRecord())); + } + + // right section + QToolButton* cloneButton = new QToolButton (this); + cloneButton->setIcon(QIcon(":/edit-clone.png")); + cloneButton->setToolTip ("Clone record"); + buttonsLayout->addWidget(cloneButton); + + QToolButton* addButton = new QToolButton (this); + addButton->setIcon(QIcon(":/add.png")); + addButton->setToolTip ("Add new record"); + buttonsLayout->addWidget(addButton); + + QToolButton* deleteButton = new QToolButton (this); + deleteButton->setIcon(QIcon(":/edit-delete.png")); + deleteButton->setToolTip ("Delete record"); + buttonsLayout->addWidget(deleteButton); + + QToolButton* revertButton = new QToolButton (this); + revertButton->setIcon(QIcon(":/edit-undo.png")); + revertButton->setToolTip ("Revert record"); + buttonsLayout->addWidget(revertButton); + + setLayout (buttonsLayout); + + // disabling and connections + if(!mBottom || !mBottom->canCreateAndDelete()) + { + cloneButton->setDisabled (true); + addButton->setDisabled (true); + deleteButton->setDisabled (true); + } + else + { + connect (addButton, SIGNAL (clicked()), mBottom, SLOT (createRequest())); + connect (cloneButton, SIGNAL (clicked()), this, SIGNAL (cloneRequest())); + } + + connect (nextButton, SIGNAL (clicked()), this, SIGNAL (nextId())); + connect (prevButton, SIGNAL (clicked()), this, SIGNAL (prevId())); + + if (!mCommandDispatcher) + { + revertButton->setDisabled (true); + deleteButton->setDisabled (true); + } + else + { + connect (revertButton, SIGNAL (clicked()), mCommandDispatcher, SLOT (executeRevert())); + connect (deleteButton, SIGNAL (clicked()), mCommandDispatcher, SLOT (executeDelete())); + } +} diff --git a/apps/opencs/view/world/recordbuttonbar.hpp b/apps/opencs/view/world/recordbuttonbar.hpp new file mode 100644 index 000000000..28e59407f --- /dev/null +++ b/apps/opencs/view/world/recordbuttonbar.hpp @@ -0,0 +1,54 @@ +#ifndef CSV_WORLD_RECORDBUTTONBAR_H +#define CSV_WORLD_RECORDBUTTONBAR_H + +#include + +namespace CSMWorld +{ + class IdTable; + class CommandDispatcher; +} + +namespace CSVWorld +{ + class TableBottomBox; + + /// \brief Button bar for use in dialogue-type subviews + /// + /// Contains the following buttons: + /// - next/prev + /// - clone + /// - add + /// - delete + /// - revert + /// - preview (optional) + /// - view (optional) + class RecordButtonBar : public QWidget + { + Q_OBJECT + + CSMWorld::IdTable& mTable; + TableBottomBox *mBottom; + CSMWorld::CommandDispatcher *mCommandDispatcher; + + public: + + RecordButtonBar (CSMWorld::IdTable& table, TableBottomBox *bottomBox = 0, + CSMWorld::CommandDispatcher *commandDispatcher = 0, QWidget *parent = 0); + + signals: + + void showPreview(); + + void viewRecord(); + + void nextId(); + + void prevId(); + + void cloneRequest(); + + }; +} + +#endif From 7f1129df3b22334f6531d82f9dee95f26bb860e3 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 27 Jun 2015 12:53:46 +0200 Subject: [PATCH 03/10] cleaned up DialogueSubView constructor; moved bottom box below button bar --- apps/opencs/view/world/dialoguesubview.cpp | 26 +++++++++++++--------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index a2f25df44..5669d9680 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -706,23 +706,27 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, : SimpleDialogueSubView (id, document) { // bottom box - getMainLayout().addWidget (mBottom = new TableBottomBox (creatorFactory, document, id, this)); + mBottom = new TableBottomBox (creatorFactory, document, id, this); - mBottom->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); + mBottom->setSizePolicy (QSizePolicy::Ignored, QSizePolicy::Fixed); - connect(mBottom, SIGNAL(requestFocus(const std::string&)), this, SLOT(requestFocus(const std::string&))); + connect (mBottom, SIGNAL (requestFocus (const std::string&)), + this, SLOT (requestFocus (const std::string&))); - // buttons + // button bar RecordButtonBar *buttons = new RecordButtonBar (getTable(), mBottom, &getCommandDispatcher(), this); - - getMainLayout().addWidget (buttons); - connect (buttons, SIGNAL(nextId()), this, SLOT(nextId())); - connect (buttons, SIGNAL (prevId()), this, SLOT(prevId())); - connect (buttons, SIGNAL (cloneRequest()), this, SLOT(cloneRequest())); - connect (buttons, SIGNAL (showPreview()), this, SLOT(showPreview())); - connect (buttons, SIGNAL (viewRecord()), this, SLOT(viewRecord())); + // layout + getMainLayout().addWidget (buttons); + getMainLayout().addWidget (mBottom); + + // connections + connect (buttons, SIGNAL (nextId()), this, SLOT (nextId())); + connect (buttons, SIGNAL (prevId()), this, SLOT (prevId())); + connect (buttons, SIGNAL (cloneRequest()), this, SLOT (cloneRequest())); + connect (buttons, SIGNAL (showPreview()), this, SLOT (showPreview())); + connect (buttons, SIGNAL (viewRecord()), this, SLOT (viewRecord())); } void CSVWorld::DialogueSubView::cloneRequest() From 67694793586200ec9b2ff48ceacccdeda65d89ee Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 27 Jun 2015 13:47:07 +0200 Subject: [PATCH 04/10] moved code for initiating record cloning from DialogueSubView to RecordButtonBar --- apps/opencs/view/doc/subview.cpp | 1 + apps/opencs/view/doc/subview.hpp | 2 ++ apps/opencs/view/world/dialoguesubview.cpp | 12 +++------ apps/opencs/view/world/dialoguesubview.hpp | 2 -- apps/opencs/view/world/recordbuttonbar.cpp | 30 +++++++++++++++++++--- apps/opencs/view/world/recordbuttonbar.hpp | 17 +++++++++--- 6 files changed, 46 insertions(+), 18 deletions(-) diff --git a/apps/opencs/view/doc/subview.cpp b/apps/opencs/view/doc/subview.cpp index f4f0c6afe..e0c2fbc46 100644 --- a/apps/opencs/view/doc/subview.cpp +++ b/apps/opencs/view/doc/subview.cpp @@ -45,6 +45,7 @@ void CSVDoc::SubView::setUniversalId (const CSMWorld::UniversalId& id) { mUniversalId = id; setWindowTitle (QString::fromUtf8(mUniversalId.toString().c_str())); + emit universalIdChanged (mUniversalId); } void CSVDoc::SubView::closeEvent (QCloseEvent *event) diff --git a/apps/opencs/view/doc/subview.hpp b/apps/opencs/view/doc/subview.hpp index b323f9ed9..189bb40eb 100644 --- a/apps/opencs/view/doc/subview.hpp +++ b/apps/opencs/view/doc/subview.hpp @@ -68,6 +68,8 @@ namespace CSVDoc void updateSubViewIndicies (SubView *view = 0); + void universalIdChanged (const CSMWorld::UniversalId& universalId); + protected slots: void closeRequest(); diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 5669d9680..92b9807e8 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -714,7 +714,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, this, SLOT (requestFocus (const std::string&))); // button bar - RecordButtonBar *buttons = new RecordButtonBar (getTable(), mBottom, + RecordButtonBar *buttons = new RecordButtonBar (id, getTable(), mBottom, &getCommandDispatcher(), this); // layout @@ -724,16 +724,10 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, // connections connect (buttons, SIGNAL (nextId()), this, SLOT (nextId())); connect (buttons, SIGNAL (prevId()), this, SLOT (prevId())); - connect (buttons, SIGNAL (cloneRequest()), this, SLOT (cloneRequest())); connect (buttons, SIGNAL (showPreview()), this, SLOT (showPreview())); connect (buttons, SIGNAL (viewRecord()), this, SLOT (viewRecord())); -} - -void CSVWorld::DialogueSubView::cloneRequest() -{ - mBottom->cloneRequest (getCurrentId(), - static_cast (getTable(). - data (getTable().getModelIndex(getCurrentId(), 2)).toInt())); + connect (this, SIGNAL (universalIdChanged (const CSMWorld::UniversalId&)), + buttons, SLOT (universalIdChanged (const CSMWorld::UniversalId&))); } void CSVWorld::DialogueSubView::prevId() diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 5d6915d42..6c0fcc59b 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -231,8 +231,6 @@ namespace CSVWorld private slots: - void cloneRequest(); - void nextId(); void prevId(); diff --git a/apps/opencs/view/world/recordbuttonbar.cpp b/apps/opencs/view/world/recordbuttonbar.cpp index 2f5395317..1560a31a5 100644 --- a/apps/opencs/view/world/recordbuttonbar.cpp +++ b/apps/opencs/view/world/recordbuttonbar.cpp @@ -9,9 +9,11 @@ #include "../world/tablebottombox.hpp" -CSVWorld::RecordButtonBar::RecordButtonBar (CSMWorld::IdTable& table, TableBottomBox *bottomBox, +CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id, + CSMWorld::IdTable& table, TableBottomBox *bottomBox, CSMWorld::CommandDispatcher *commandDispatcher, QWidget *parent) -: QWidget (parent), mTable (table), mBottom (bottomBox), mCommandDispatcher (commandDispatcher) +: QWidget (parent), mId (id), mTable (table), mBottom (bottomBox), + mCommandDispatcher (commandDispatcher) { QHBoxLayout *buttonsLayout = new QHBoxLayout; buttonsLayout->setContentsMargins (0, 0, 0, 0); @@ -81,7 +83,7 @@ CSVWorld::RecordButtonBar::RecordButtonBar (CSMWorld::IdTable& table, TableBotto else { connect (addButton, SIGNAL (clicked()), mBottom, SLOT (createRequest())); - connect (cloneButton, SIGNAL (clicked()), this, SIGNAL (cloneRequest())); + connect (cloneButton, SIGNAL (clicked()), this, SLOT (cloneRequest())); } connect (nextButton, SIGNAL (clicked()), this, SIGNAL (nextId())); @@ -98,3 +100,25 @@ CSVWorld::RecordButtonBar::RecordButtonBar (CSMWorld::IdTable& table, TableBotto connect (deleteButton, SIGNAL (clicked()), mCommandDispatcher, SLOT (executeDelete())); } } + +void CSVWorld::RecordButtonBar::universalIdChanged (const CSMWorld::UniversalId& id) +{ + mId = id; +} + +void CSVWorld::RecordButtonBar::cloneRequest() +{ + if (mBottom) + { + int typeColumn = mTable.searchColumnIndex (CSMWorld::Columns::ColumnId_RecordType); + + if (typeColumn!=-1) + { + QModelIndex typeIndex = mTable.getModelIndex (mId.getId(), typeColumn); + CSMWorld::UniversalId::Type type = static_cast ( + mTable.data (typeIndex).toInt()); + + mBottom->cloneRequest (mId.getId(), type); + } + } +} diff --git a/apps/opencs/view/world/recordbuttonbar.hpp b/apps/opencs/view/world/recordbuttonbar.hpp index 28e59407f..08f16a687 100644 --- a/apps/opencs/view/world/recordbuttonbar.hpp +++ b/apps/opencs/view/world/recordbuttonbar.hpp @@ -3,6 +3,8 @@ #include +#include "../../model/world/universalid.hpp" + namespace CSMWorld { class IdTable; @@ -27,15 +29,25 @@ namespace CSVWorld { Q_OBJECT + CSMWorld::UniversalId mId; CSMWorld::IdTable& mTable; TableBottomBox *mBottom; CSMWorld::CommandDispatcher *mCommandDispatcher; public: - RecordButtonBar (CSMWorld::IdTable& table, TableBottomBox *bottomBox = 0, + RecordButtonBar (const CSMWorld::UniversalId& id, + CSMWorld::IdTable& table, TableBottomBox *bottomBox = 0, CSMWorld::CommandDispatcher *commandDispatcher = 0, QWidget *parent = 0); + public slots: + + void universalIdChanged (const CSMWorld::UniversalId& id); + + private slots: + + void cloneRequest(); + signals: void showPreview(); @@ -45,9 +57,6 @@ namespace CSVWorld void nextId(); void prevId(); - - void cloneRequest(); - }; } From d5e6d8a58bf666518cb21e7508e8f28b335effd4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 27 Jun 2015 14:25:48 +0200 Subject: [PATCH 05/10] disable dialogue subview buttons while document is locked --- apps/opencs/view/world/dialoguesubview.cpp | 20 ++++-- apps/opencs/view/world/dialoguesubview.hpp | 5 ++ apps/opencs/view/world/recordbuttonbar.cpp | 81 ++++++++++++---------- apps/opencs/view/world/recordbuttonbar.hpp | 13 ++++ 4 files changed, 77 insertions(+), 42 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 92b9807e8..ffb606497 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -714,20 +714,26 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, this, SLOT (requestFocus (const std::string&))); // button bar - RecordButtonBar *buttons = new RecordButtonBar (id, getTable(), mBottom, + mButtons = new RecordButtonBar (id, getTable(), mBottom, &getCommandDispatcher(), this); // layout - getMainLayout().addWidget (buttons); + getMainLayout().addWidget (mButtons); getMainLayout().addWidget (mBottom); // connections - connect (buttons, SIGNAL (nextId()), this, SLOT (nextId())); - connect (buttons, SIGNAL (prevId()), this, SLOT (prevId())); - connect (buttons, SIGNAL (showPreview()), this, SLOT (showPreview())); - connect (buttons, SIGNAL (viewRecord()), this, SLOT (viewRecord())); + connect (mButtons, SIGNAL (nextId()), this, SLOT (nextId())); + connect (mButtons, SIGNAL (prevId()), this, SLOT (prevId())); + connect (mButtons, SIGNAL (showPreview()), this, SLOT (showPreview())); + connect (mButtons, SIGNAL (viewRecord()), this, SLOT (viewRecord())); connect (this, SIGNAL (universalIdChanged (const CSMWorld::UniversalId&)), - buttons, SLOT (universalIdChanged (const CSMWorld::UniversalId&))); + mButtons, SLOT (universalIdChanged (const CSMWorld::UniversalId&))); +} + +void CSVWorld::DialogueSubView::setEditLock (bool locked) +{ + SimpleDialogueSubView::setEditLock (locked); + mButtons->setEditLock (locked); } void CSVWorld::DialogueSubView::prevId() diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 6c0fcc59b..63b25d06e 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -218,17 +218,22 @@ namespace CSVWorld void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); }; + class RecordButtonBar; + class DialogueSubView : public SimpleDialogueSubView { Q_OBJECT TableBottomBox* mBottom; + RecordButtonBar *mButtons; public: DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, const CreatorFactoryBase& creatorFactory, bool sorting = false); + virtual void setEditLock (bool locked); + private slots: void nextId(); diff --git a/apps/opencs/view/world/recordbuttonbar.cpp b/apps/opencs/view/world/recordbuttonbar.cpp index 1560a31a5..93a6a5823 100644 --- a/apps/opencs/view/world/recordbuttonbar.cpp +++ b/apps/opencs/view/world/recordbuttonbar.cpp @@ -9,11 +9,25 @@ #include "../world/tablebottombox.hpp" +void CSVWorld::RecordButtonBar::updateModificationButtons() +{ + bool createAndDeleteDisabled = !mBottom || !mBottom->canCreateAndDelete() || mLocked; + + mCloneButton->setDisabled (createAndDeleteDisabled); + mAddButton->setDisabled (createAndDeleteDisabled); + mDeleteButton->setDisabled (createAndDeleteDisabled); + + bool commandDisabled = !mCommandDispatcher || mLocked; + + mRevertButton->setDisabled (commandDisabled); + mDeleteButton->setDisabled (commandDisabled); +} + CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id, CSMWorld::IdTable& table, TableBottomBox *bottomBox, CSMWorld::CommandDispatcher *commandDispatcher, QWidget *parent) : QWidget (parent), mId (id), mTable (table), mBottom (bottomBox), - mCommandDispatcher (commandDispatcher) + mCommandDispatcher (commandDispatcher), mLocked (false) { QHBoxLayout *buttonsLayout = new QHBoxLayout; buttonsLayout->setContentsMargins (0, 0, 0, 0); @@ -51,54 +65,51 @@ CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id, } // right section - QToolButton* cloneButton = new QToolButton (this); - cloneButton->setIcon(QIcon(":/edit-clone.png")); - cloneButton->setToolTip ("Clone record"); - buttonsLayout->addWidget(cloneButton); + mCloneButton = new QToolButton (this); + mCloneButton->setIcon(QIcon(":/edit-clone.png")); + mCloneButton->setToolTip ("Clone record"); + buttonsLayout->addWidget(mCloneButton); - QToolButton* addButton = new QToolButton (this); - addButton->setIcon(QIcon(":/add.png")); - addButton->setToolTip ("Add new record"); - buttonsLayout->addWidget(addButton); + mAddButton = new QToolButton (this); + mAddButton->setIcon(QIcon(":/add.png")); + mAddButton->setToolTip ("Add new record"); + buttonsLayout->addWidget(mAddButton); - QToolButton* deleteButton = new QToolButton (this); - deleteButton->setIcon(QIcon(":/edit-delete.png")); - deleteButton->setToolTip ("Delete record"); - buttonsLayout->addWidget(deleteButton); + mDeleteButton = new QToolButton (this); + mDeleteButton->setIcon(QIcon(":/edit-delete.png")); + mDeleteButton->setToolTip ("Delete record"); + buttonsLayout->addWidget(mDeleteButton); - QToolButton* revertButton = new QToolButton (this); - revertButton->setIcon(QIcon(":/edit-undo.png")); - revertButton->setToolTip ("Revert record"); - buttonsLayout->addWidget(revertButton); + mRevertButton = new QToolButton (this); + mRevertButton->setIcon(QIcon(":/edit-undo.png")); + mRevertButton->setToolTip ("Revert record"); + buttonsLayout->addWidget(mRevertButton); setLayout (buttonsLayout); - // disabling and connections - if(!mBottom || !mBottom->canCreateAndDelete()) + // connections + if(mBottom && mBottom->canCreateAndDelete()) { - cloneButton->setDisabled (true); - addButton->setDisabled (true); - deleteButton->setDisabled (true); - } - else - { - connect (addButton, SIGNAL (clicked()), mBottom, SLOT (createRequest())); - connect (cloneButton, SIGNAL (clicked()), this, SLOT (cloneRequest())); + connect (mAddButton, SIGNAL (clicked()), mBottom, SLOT (createRequest())); + connect (mCloneButton, SIGNAL (clicked()), this, SLOT (cloneRequest())); } connect (nextButton, SIGNAL (clicked()), this, SIGNAL (nextId())); connect (prevButton, SIGNAL (clicked()), this, SIGNAL (prevId())); - if (!mCommandDispatcher) + if (mCommandDispatcher) { - revertButton->setDisabled (true); - deleteButton->setDisabled (true); - } - else - { - connect (revertButton, SIGNAL (clicked()), mCommandDispatcher, SLOT (executeRevert())); - connect (deleteButton, SIGNAL (clicked()), mCommandDispatcher, SLOT (executeDelete())); + connect (mRevertButton, SIGNAL (clicked()), mCommandDispatcher, SLOT (executeRevert())); + connect (mDeleteButton, SIGNAL (clicked()), mCommandDispatcher, SLOT (executeDelete())); } + + updateModificationButtons(); +} + +void CSVWorld::RecordButtonBar::setEditLock (bool locked) +{ + mLocked = locked; + updateModificationButtons(); } void CSVWorld::RecordButtonBar::universalIdChanged (const CSMWorld::UniversalId& id) diff --git a/apps/opencs/view/world/recordbuttonbar.hpp b/apps/opencs/view/world/recordbuttonbar.hpp index 08f16a687..95b567594 100644 --- a/apps/opencs/view/world/recordbuttonbar.hpp +++ b/apps/opencs/view/world/recordbuttonbar.hpp @@ -5,6 +5,8 @@ #include "../../model/world/universalid.hpp" +class QToolButton; + namespace CSMWorld { class IdTable; @@ -33,13 +35,24 @@ namespace CSVWorld CSMWorld::IdTable& mTable; TableBottomBox *mBottom; CSMWorld::CommandDispatcher *mCommandDispatcher; + QToolButton *mCloneButton; + QToolButton *mAddButton; + QToolButton *mDeleteButton; + QToolButton *mRevertButton; + bool mLocked; + private: + + void updateModificationButtons(); + public: RecordButtonBar (const CSMWorld::UniversalId& id, CSMWorld::IdTable& table, TableBottomBox *bottomBox = 0, CSMWorld::CommandDispatcher *commandDispatcher = 0, QWidget *parent = 0); + void setEditLock (bool locked); + public slots: void universalIdChanged (const CSMWorld::UniversalId& id); From a8c26ec0c11a5252de2e75fd26d9d83ef1afc13e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 27 Jun 2015 14:42:22 +0200 Subject: [PATCH 06/10] moved most of the code for next/prev buttons from DialogueSubView to RecordBUttonBar --- apps/opencs/view/world/dialoguesubview.cpp | 88 ++++------------------ apps/opencs/view/world/dialoguesubview.hpp | 6 +- apps/opencs/view/world/recordbuttonbar.cpp | 28 ++++++- apps/opencs/view/world/recordbuttonbar.hpp | 8 +- 4 files changed, 47 insertions(+), 83 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index ffb606497..cf9d69f02 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -722,10 +722,10 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, getMainLayout().addWidget (mBottom); // connections - connect (mButtons, SIGNAL (nextId()), this, SLOT (nextId())); - connect (mButtons, SIGNAL (prevId()), this, SLOT (prevId())); connect (mButtons, SIGNAL (showPreview()), this, SLOT (showPreview())); connect (mButtons, SIGNAL (viewRecord()), this, SLOT (viewRecord())); + connect (mButtons, SIGNAL (switchToRow (int)), this, SLOT (switchToRow (int))); + connect (this, SIGNAL (universalIdChanged (const CSMWorld::UniversalId&)), mButtons, SLOT (universalIdChanged (const CSMWorld::UniversalId&))); } @@ -736,78 +736,6 @@ void CSVWorld::DialogueSubView::setEditLock (bool locked) mButtons->setEditLock (locked); } -void CSVWorld::DialogueSubView::prevId() -{ - int newRow = getTable().getModelIndex (getCurrentId(), 0).row() - 1; - - if (newRow < 0) - { - return; - } - while (newRow >= 0) - { - QModelIndex newIndex (getTable().index(newRow, 0)); - - if (!newIndex.isValid()) - { - return; - } - - CSMWorld::RecordBase::State state = static_cast (getTable().data (getTable().index (newRow, 1)).toInt()); - if (!(state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased)) - { - getEditWidget().remake (newRow); - - setUniversalId(CSMWorld::UniversalId (static_cast (getTable().data (getTable().index (newRow, 2)).toInt()), - getTable().data (getTable().index (newRow, 0)).toString().toUtf8().constData())); - - changeCurrentId(std::string (getTable().data (getTable().index (newRow, 0)).toString().toUtf8().constData())); - - getEditWidget().setDisabled (isLocked()); - - return; - } - --newRow; - } -} - -void CSVWorld::DialogueSubView::nextId () -{ - int newRow = getTable().getModelIndex (getCurrentId(), 0).row() + 1; - - if (newRow >= getTable().rowCount()) - { - return; - } - - while (newRow < getTable().rowCount()) - { - QModelIndex newIndex (getTable().index(newRow, 0)); - - if (!newIndex.isValid()) - { - return; - } - - CSMWorld::RecordBase::State state = static_cast (getTable().data (getTable().index (newRow, 1)).toInt()); - if (!(state == CSMWorld::RecordBase::State_Deleted)) - { - getEditWidget().remake(newRow); - - setUniversalId(CSMWorld::UniversalId (static_cast (getTable().data (getTable().index (newRow, 2)).toInt()), - getTable().data (getTable().index (newRow, 0)).toString().toUtf8().constData())); - - changeCurrentId(std::string (getTable().data (getTable().index (newRow, 0)).toString().toUtf8().constData())); - - getEditWidget().setDisabled (isLocked()); - - return; - } - ++newRow; - } -} - - void CSVWorld::DialogueSubView::showPreview () { QModelIndex currentIndex (getTable().getModelIndex (getCurrentId(), 0)); @@ -833,3 +761,15 @@ void CSVWorld::DialogueSubView::viewRecord () emit focusId (params.first, params.second); } } + +void CSVWorld::DialogueSubView::switchToRow (int row) +{ + getEditWidget().remake (row); + + setUniversalId (CSMWorld::UniversalId (static_cast (getTable().data (getTable().index (row, 2)).toInt()), + getTable().data (getTable().index (row, 0)).toString().toUtf8().constData())); + + changeCurrentId(std::string (getTable().data (getTable().index (row, 0)).toString().toUtf8().constData())); + + getEditWidget().setDisabled (isLocked()); +} diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 63b25d06e..ff70a37d3 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -236,13 +236,11 @@ namespace CSVWorld private slots: - void nextId(); - - void prevId(); - void showPreview(); void viewRecord(); + + void switchToRow (int row); }; } diff --git a/apps/opencs/view/world/recordbuttonbar.cpp b/apps/opencs/view/world/recordbuttonbar.cpp index 93a6a5823..375ab68c3 100644 --- a/apps/opencs/view/world/recordbuttonbar.cpp +++ b/apps/opencs/view/world/recordbuttonbar.cpp @@ -94,8 +94,8 @@ CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id, connect (mCloneButton, SIGNAL (clicked()), this, SLOT (cloneRequest())); } - connect (nextButton, SIGNAL (clicked()), this, SIGNAL (nextId())); - connect (prevButton, SIGNAL (clicked()), this, SIGNAL (prevId())); + connect (nextButton, SIGNAL (clicked()), this, SLOT (nextId())); + connect (prevButton, SIGNAL (clicked()), this, SLOT (prevId())); if (mCommandDispatcher) { @@ -133,3 +133,27 @@ void CSVWorld::RecordButtonBar::cloneRequest() } } } + +void CSVWorld::RecordButtonBar::nextId() +{ + int newRow = mTable.getModelIndex (mId.getId(), 0).row() + 1; + + if (newRow >= mTable.rowCount()) + { + return; + } + + emit switchToRow (newRow); +} + +void CSVWorld::RecordButtonBar::prevId() +{ + int newRow = mTable.getModelIndex (mId.getId(), 0).row() - 1; + + if (newRow < 0) + { + return; + } + + emit switchToRow (newRow); +} diff --git a/apps/opencs/view/world/recordbuttonbar.hpp b/apps/opencs/view/world/recordbuttonbar.hpp index 95b567594..6a5fadca5 100644 --- a/apps/opencs/view/world/recordbuttonbar.hpp +++ b/apps/opencs/view/world/recordbuttonbar.hpp @@ -60,6 +60,10 @@ namespace CSVWorld private slots: void cloneRequest(); + + void nextId(); + + void prevId(); signals: @@ -67,9 +71,7 @@ namespace CSVWorld void viewRecord(); - void nextId(); - - void prevId(); + void switchToRow (int row); }; } From 9aa153984aa0e5b8cfe347eadada6b1be262b0c4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 27 Jun 2015 15:02:50 +0200 Subject: [PATCH 07/10] fixed inconsistent handling of deleted records in dialogue; general cleanup --- apps/opencs/view/world/dialoguesubview.cpp | 19 ++++++++++++++----- apps/opencs/view/world/recordbuttonbar.cpp | 15 ++++++--------- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index cf9d69f02..4ef06766c 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -764,12 +764,21 @@ void CSVWorld::DialogueSubView::viewRecord () void CSVWorld::DialogueSubView::switchToRow (int row) { + int idColumn = getTable().findColumnIndex (CSMWorld::Columns::ColumnId_Id); + std::string id = getTable().data (getTable().index (row, idColumn)).toString().toUtf8().constData(); + + int typeColumn = getTable().findColumnIndex (CSMWorld::Columns::ColumnId_RecordType); + CSMWorld::UniversalId::Type type = static_cast ( + getTable().data (getTable().index (row, typeColumn)).toInt()); + + setUniversalId (CSMWorld::UniversalId (type, id)); + changeCurrentId (id); + getEditWidget().remake (row); - setUniversalId (CSMWorld::UniversalId (static_cast (getTable().data (getTable().index (row, 2)).toInt()), - getTable().data (getTable().index (row, 0)).toString().toUtf8().constData())); + int stateColumn = getTable().findColumnIndex (CSMWorld::Columns::ColumnId_Modification); + CSMWorld::RecordBase::State state = static_cast ( + getTable().data (getTable().index (row, stateColumn)).toInt()); - changeCurrentId(std::string (getTable().data (getTable().index (row, 0)).toString().toUtf8().constData())); - - getEditWidget().setDisabled (isLocked()); + getEditWidget().setDisabled (isLocked() || state==CSMWorld::RecordBase::State_Deleted); } diff --git a/apps/opencs/view/world/recordbuttonbar.cpp b/apps/opencs/view/world/recordbuttonbar.cpp index 375ab68c3..db2320341 100644 --- a/apps/opencs/view/world/recordbuttonbar.cpp +++ b/apps/opencs/view/world/recordbuttonbar.cpp @@ -121,16 +121,13 @@ void CSVWorld::RecordButtonBar::cloneRequest() { if (mBottom) { - int typeColumn = mTable.searchColumnIndex (CSMWorld::Columns::ColumnId_RecordType); + int typeColumn = mTable.findColumnIndex (CSMWorld::Columns::ColumnId_RecordType); - if (typeColumn!=-1) - { - QModelIndex typeIndex = mTable.getModelIndex (mId.getId(), typeColumn); - CSMWorld::UniversalId::Type type = static_cast ( - mTable.data (typeIndex).toInt()); - - mBottom->cloneRequest (mId.getId(), type); - } + QModelIndex typeIndex = mTable.getModelIndex (mId.getId(), typeColumn); + CSMWorld::UniversalId::Type type = static_cast ( + mTable.data (typeIndex).toInt()); + + mBottom->cloneRequest (mId.getId(), type); } } From 95522fcad29cd72a58c16fa064b5bd9553689642 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 27 Jun 2015 15:29:54 +0200 Subject: [PATCH 08/10] more general cleanup --- apps/opencs/view/world/dialoguesubview.cpp | 51 +++++++++------------- apps/opencs/view/world/dialoguesubview.hpp | 24 +++++----- 2 files changed, 31 insertions(+), 44 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 4ef06766c..69255f821 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -17,8 +17,6 @@ #include #include #include -#include -#include #include #include @@ -573,11 +571,6 @@ CSMWorld::CommandDispatcher& CSVWorld::SimpleDialogueSubView::getCommandDispatch return mCommandDispatcher; } -std::string CSVWorld::SimpleDialogueSubView::getCurrentId() const -{ - return mCurrentId; -} - CSVWorld::EditWidget& CSVWorld::SimpleDialogueSubView::getEditWidget() { return *mEditWidget; @@ -593,7 +586,6 @@ CSVWorld::SimpleDialogueSubView::SimpleDialogueSubView (const CSMWorld::Universa mEditWidget(0), mMainLayout(NULL), mTable(dynamic_cast(document.getData().getTableModel(id))), - mUndoStack(document.getUndoStack()), mLocked(false), mDocument(document), mCommandDispatcher (document, CSMWorld::UniversalId::getParentType (id.getType())) @@ -601,7 +593,7 @@ CSVWorld::SimpleDialogueSubView::SimpleDialogueSubView (const CSMWorld::Universa connect(mTable, SIGNAL(dataChanged (const QModelIndex&, const QModelIndex&)), this, SLOT(dataChanged(const QModelIndex&))); connect(mTable, SIGNAL(rowsAboutToBeRemoved(const QModelIndex&, int, int)), this, SLOT(rowsAboutToBeRemoved(const QModelIndex&, int, int))); - changeCurrentId(id.getId()); + updateCurrentId(); QWidget *mainWidget = new QWidget(this); @@ -609,21 +601,21 @@ CSVWorld::SimpleDialogueSubView::SimpleDialogueSubView (const CSMWorld::Universa setWidget (mainWidget); mEditWidget = new EditWidget(mainWidget, - mTable->getModelIndex(mCurrentId, 0).row(), mTable, mCommandDispatcher, document, false); + mTable->getModelIndex(getUniversalId().getId(), 0).row(), mTable, mCommandDispatcher, document, false); mMainLayout->addWidget(mEditWidget); mEditWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - dataChanged(mTable->getModelIndex (mCurrentId, 0)); + dataChanged(mTable->getModelIndex (getUniversalId().getId(), 0)); } void CSVWorld::SimpleDialogueSubView::setEditLock (bool locked) { - if (!mEditWidget) // hack to indicate that mCurrentId is no longer valid + if (!mEditWidget) // hack to indicate that getUniversalId().getId() is no longer valid return; mLocked = locked; - QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); + QModelIndex currentIndex(mTable->getModelIndex(getUniversalId().getId(), 0)); if (currentIndex.isValid()) { @@ -638,7 +630,7 @@ void CSVWorld::SimpleDialogueSubView::setEditLock (bool locked) void CSVWorld::SimpleDialogueSubView::dataChanged (const QModelIndex & index) { - QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); + QModelIndex currentIndex(mTable->getModelIndex(getUniversalId().getId(), 0)); if (currentIndex.isValid() && (index.parent().isValid() ? index.parent().row() : index.row()) == currentIndex.row()) @@ -671,7 +663,7 @@ void CSVWorld::SimpleDialogueSubView::dataChanged (const QModelIndex & index) void CSVWorld::SimpleDialogueSubView::rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end) { - QModelIndex currentIndex(mTable->getModelIndex(mCurrentId, 0)); + QModelIndex currentIndex(mTable->getModelIndex(getUniversalId().getId(), 0)); if (currentIndex.isValid() && currentIndex.row() >= start && currentIndex.row() <= end) { @@ -684,19 +676,10 @@ void CSVWorld::SimpleDialogueSubView::rowsAboutToBeRemoved(const QModelIndex &pa } } -void CSVWorld::SimpleDialogueSubView::requestFocus (const std::string& id) -{ - changeCurrentId(id); - - mEditWidget->remake(mTable->getModelIndex (id, 0).row()); -} - -void CSVWorld::SimpleDialogueSubView::changeCurrentId (const std::string& newId) +void CSVWorld::SimpleDialogueSubView::updateCurrentId() { std::vector selection; - mCurrentId = std::string(newId); - - selection.push_back(mCurrentId); + selection.push_back (getUniversalId().getId()); mCommandDispatcher.setSelection(selection); } @@ -738,19 +721,19 @@ void CSVWorld::DialogueSubView::setEditLock (bool locked) void CSVWorld::DialogueSubView::showPreview () { - QModelIndex currentIndex (getTable().getModelIndex (getCurrentId(), 0)); + QModelIndex currentIndex (getTable().getModelIndex (getUniversalId().getId(), 0)); if (currentIndex.isValid() && getTable().getFeatures() & CSMWorld::IdTable::Feature_Preview && currentIndex.row() < getTable().rowCount()) { - emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, getCurrentId()), ""); + emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, getUniversalId().getId()), ""); } } void CSVWorld::DialogueSubView::viewRecord () { - QModelIndex currentIndex (getTable().getModelIndex (getCurrentId(), 0)); + QModelIndex currentIndex (getTable().getModelIndex (getUniversalId().getId(), 0)); if (currentIndex.isValid() && currentIndex.row() < getTable().rowCount()) @@ -772,7 +755,7 @@ void CSVWorld::DialogueSubView::switchToRow (int row) getTable().data (getTable().index (row, typeColumn)).toInt()); setUniversalId (CSMWorld::UniversalId (type, id)); - changeCurrentId (id); + updateCurrentId(); getEditWidget().remake (row); @@ -782,3 +765,11 @@ void CSVWorld::DialogueSubView::switchToRow (int row) getEditWidget().setDisabled (isLocked() || state==CSMWorld::RecordBase::State_Deleted); } + +void CSVWorld::DialogueSubView::requestFocus (const std::string& id) +{ + QModelIndex index = getTable().getModelIndex (id, 0); + + if (index.isValid()) + switchToRow (index.row()); +} diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index ff70a37d3..aec98d69c 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -175,16 +175,14 @@ namespace CSVWorld class SimpleDialogueSubView : public CSVDoc::SubView { - Q_OBJECT + Q_OBJECT - EditWidget* mEditWidget; - QVBoxLayout* mMainLayout; - CSMWorld::IdTable* mTable; - QUndoStack& mUndoStack; - std::string mCurrentId; - bool mLocked; - const CSMDoc::Document& mDocument; - CSMWorld::CommandDispatcher mCommandDispatcher; + EditWidget* mEditWidget; + QVBoxLayout* mMainLayout; + CSMWorld::IdTable* mTable; + bool mLocked; + const CSMDoc::Document& mDocument; + CSMWorld::CommandDispatcher mCommandDispatcher; protected: @@ -194,11 +192,9 @@ namespace CSVWorld CSMWorld::CommandDispatcher& getCommandDispatcher(); - std::string getCurrentId() const; - EditWidget& getEditWidget(); - void changeCurrentId(const std::string& newCurrent); + void updateCurrentId(); bool isLocked() const; @@ -213,8 +209,6 @@ namespace CSVWorld void dataChanged(const QModelIndex & index); ///\brief we need to care for deleting currently edited record - void requestFocus (const std::string& id); - void rowsAboutToBeRemoved(const QModelIndex &parent, int start, int end); }; @@ -241,6 +235,8 @@ namespace CSVWorld void viewRecord(); void switchToRow (int row); + + void requestFocus (const std::string& id); }; } From e27a75bd103430a3b88190b4e63612706116ba24 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 27 Jun 2015 15:56:41 +0200 Subject: [PATCH 09/10] added user setting for cyclic prev/next --- apps/opencs/model/settings/usersettings.cpp | 8 ++++++++ apps/opencs/view/world/recordbuttonbar.cpp | 16 +++++++++++++--- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 3e59d0582..bcf7c3ba9 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -356,6 +356,14 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() formatId->setToolTip ("(Default: Blue) Use one of the following formats:" + tooltip); } + declareSection ("general-input", "General Input"); + { + Setting *cycle = createSetting (Type_CheckBox, "cycle", "Cyclic next/previous"); + cycle->setDefaultValue ("false"); + cycle->setToolTip ("When using next/previous functions at the last/first item of a " + "list go to the first/last item"); + } + { /****************************************************************** * There are three types of values: diff --git a/apps/opencs/view/world/recordbuttonbar.cpp b/apps/opencs/view/world/recordbuttonbar.cpp index db2320341..5dcc1d5cd 100644 --- a/apps/opencs/view/world/recordbuttonbar.cpp +++ b/apps/opencs/view/world/recordbuttonbar.cpp @@ -7,6 +7,8 @@ #include "../../model/world/idtable.hpp" #include "../../model/world/commanddispatcher.hpp" +#include "../../model/settings/usersettings.hpp" + #include "../world/tablebottombox.hpp" void CSVWorld::RecordButtonBar::updateModificationButtons() @@ -132,12 +134,16 @@ void CSVWorld::RecordButtonBar::cloneRequest() } void CSVWorld::RecordButtonBar::nextId() -{ +{ int newRow = mTable.getModelIndex (mId.getId(), 0).row() + 1; if (newRow >= mTable.rowCount()) { - return; + if (CSMSettings::UserSettings::instance().settingValue ("general-input/cycle") + =="true") + newRow = 0; + else + return; } emit switchToRow (newRow); @@ -149,7 +155,11 @@ void CSVWorld::RecordButtonBar::prevId() if (newRow < 0) { - return; + if (CSMSettings::UserSettings::instance().settingValue ("general-input/cycle") + =="true") + newRow = mTable.rowCount()-1; + else + return; } emit switchToRow (newRow); From 15bb2855a99d548b3f13aa799dc188dd0dab2b56 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 27 Jun 2015 16:57:45 +0200 Subject: [PATCH 10/10] disable prev/next buttons if there is no previous/next record --- apps/opencs/view/world/dialoguesubview.cpp | 6 +++ apps/opencs/view/world/dialoguesubview.hpp | 2 + apps/opencs/view/world/recordbuttonbar.cpp | 61 ++++++++++++++++++---- apps/opencs/view/world/recordbuttonbar.hpp | 11 +++- 4 files changed, 69 insertions(+), 11 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 69255f821..1d3eb5313 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -719,6 +719,12 @@ void CSVWorld::DialogueSubView::setEditLock (bool locked) mButtons->setEditLock (locked); } +void CSVWorld::DialogueSubView::updateUserSetting (const QString& name, const QStringList& value) +{ + SimpleDialogueSubView::updateUserSetting (name, value); + mButtons->updateUserSetting (name, value); +} + void CSVWorld::DialogueSubView::showPreview () { QModelIndex currentIndex (getTable().getModelIndex (getUniversalId().getId(), 0)); diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index aec98d69c..be58be5ad 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -228,6 +228,8 @@ namespace CSVWorld virtual void setEditLock (bool locked); + virtual void updateUserSetting (const QString& name, const QStringList& value); + private slots: void showPreview(); diff --git a/apps/opencs/view/world/recordbuttonbar.cpp b/apps/opencs/view/world/recordbuttonbar.cpp index 5dcc1d5cd..63c0dd0a1 100644 --- a/apps/opencs/view/world/recordbuttonbar.cpp +++ b/apps/opencs/view/world/recordbuttonbar.cpp @@ -25,6 +25,29 @@ void CSVWorld::RecordButtonBar::updateModificationButtons() mDeleteButton->setDisabled (commandDisabled); } +void CSVWorld::RecordButtonBar::updatePrevNextButtons() +{ + int rows = mTable.rowCount(); + + if (rows<=1) + { + mPrevButton->setDisabled (true); + mNextButton->setDisabled (true); + } + else if (CSMSettings::UserSettings::instance().settingValue ("general-input/cycle")=="true") + { + mPrevButton->setDisabled (false); + mNextButton->setDisabled (false); + } + else + { + int row = mTable.getModelIndex (mId.getId(), 0).row(); + + mPrevButton->setDisabled (row<=0); + mNextButton->setDisabled (row>=rows-1); + } +} + CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id, CSMWorld::IdTable& table, TableBottomBox *bottomBox, CSMWorld::CommandDispatcher *commandDispatcher, QWidget *parent) @@ -35,15 +58,15 @@ CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id, buttonsLayout->setContentsMargins (0, 0, 0, 0); // left section - QToolButton* prevButton = new QToolButton (this); - prevButton->setIcon(QIcon(":/go-previous.png")); - prevButton->setToolTip ("Switch to previous record"); - buttonsLayout->addWidget (prevButton, 0); + mPrevButton = new QToolButton (this); + mPrevButton->setIcon(QIcon(":/go-previous.png")); + mPrevButton->setToolTip ("Switch to previous record"); + buttonsLayout->addWidget (mPrevButton, 0); - QToolButton* nextButton = new QToolButton (this); - nextButton->setIcon(QIcon(":/go-next.png")); - nextButton->setToolTip ("Switch to next record"); - buttonsLayout->addWidget (nextButton, 1); + mNextButton = new QToolButton (this); + mNextButton->setIcon(QIcon(":/go-next.png")); + mNextButton->setToolTip ("Switch to next record"); + buttonsLayout->addWidget (mNextButton, 1); buttonsLayout->addStretch(2); @@ -96,8 +119,8 @@ CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id, connect (mCloneButton, SIGNAL (clicked()), this, SLOT (cloneRequest())); } - connect (nextButton, SIGNAL (clicked()), this, SLOT (nextId())); - connect (prevButton, SIGNAL (clicked()), this, SLOT (prevId())); + connect (mNextButton, SIGNAL (clicked()), this, SLOT (nextId())); + connect (mPrevButton, SIGNAL (clicked()), this, SLOT (prevId())); if (mCommandDispatcher) { @@ -105,7 +128,13 @@ CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id, connect (mDeleteButton, SIGNAL (clicked()), mCommandDispatcher, SLOT (executeDelete())); } + connect (&mTable, SIGNAL (rowsInserted (const QModelIndex&, int, int)), + this, SLOT (rowNumberChanged (const QModelIndex&, int, int))); + connect (&mTable, SIGNAL (rowsRemoved (const QModelIndex&, int, int)), + this, SLOT (rowNumberChanged (const QModelIndex&, int, int))); + updateModificationButtons(); + updatePrevNextButtons(); } void CSVWorld::RecordButtonBar::setEditLock (bool locked) @@ -114,9 +143,16 @@ void CSVWorld::RecordButtonBar::setEditLock (bool locked) updateModificationButtons(); } +void CSVWorld::RecordButtonBar::updateUserSetting (const QString& name, const QStringList& value) +{ + if (name=="general-input/cycle") + updatePrevNextButtons(); +} + void CSVWorld::RecordButtonBar::universalIdChanged (const CSMWorld::UniversalId& id) { mId = id; + updatePrevNextButtons(); } void CSVWorld::RecordButtonBar::cloneRequest() @@ -164,3 +200,8 @@ void CSVWorld::RecordButtonBar::prevId() emit switchToRow (newRow); } + +void CSVWorld::RecordButtonBar::rowNumberChanged (const QModelIndex& parent, int start, int end) +{ + updatePrevNextButtons(); +} diff --git a/apps/opencs/view/world/recordbuttonbar.hpp b/apps/opencs/view/world/recordbuttonbar.hpp index 6a5fadca5..93ca45518 100644 --- a/apps/opencs/view/world/recordbuttonbar.hpp +++ b/apps/opencs/view/world/recordbuttonbar.hpp @@ -6,6 +6,7 @@ #include "../../model/world/universalid.hpp" class QToolButton; +class QModelIndex; namespace CSMWorld { @@ -35,6 +36,8 @@ namespace CSVWorld CSMWorld::IdTable& mTable; TableBottomBox *mBottom; CSMWorld::CommandDispatcher *mCommandDispatcher; + QToolButton *mPrevButton; + QToolButton *mNextButton; QToolButton *mCloneButton; QToolButton *mAddButton; QToolButton *mDeleteButton; @@ -44,6 +47,8 @@ namespace CSVWorld private: void updateModificationButtons(); + + void updatePrevNextButtons(); public: @@ -52,7 +57,9 @@ namespace CSVWorld CSMWorld::CommandDispatcher *commandDispatcher = 0, QWidget *parent = 0); void setEditLock (bool locked); - + + void updateUserSetting (const QString& name, const QStringList& value); + public slots: void universalIdChanged (const CSMWorld::UniversalId& id); @@ -64,6 +71,8 @@ namespace CSVWorld void nextId(); void prevId(); + + void rowNumberChanged (const QModelIndex& parent, int start, int end); signals: