From b97a4cee44676ec44934dac69b1e16d2370492c1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 11 Jul 2015 16:09:13 +0200 Subject: [PATCH 01/19] added button bar to script subview --- apps/opencs/view/world/scriptsubview.cpp | 61 ++++++++++++++++++------ apps/opencs/view/world/scriptsubview.hpp | 7 +++ 2 files changed, 54 insertions(+), 14 deletions(-) diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index 411eb3660d..dc079c3a9f 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -15,26 +15,20 @@ #include "../../model/settings/usersettings.hpp" #include "scriptedit.hpp" +#include "recordbuttonbar.hpp" CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) -: SubView (id), mDocument (document), mColumn (-1), mBottom(0), mStatus(0) +: SubView (id), mDocument (document), mColumn (-1), mBottom(0), mStatus(0), + mCommandDispatcher (document, CSMWorld::UniversalId::getParentType (id.getType())) { + std::vector selection (1, id.getId()); + mCommandDispatcher.setSelection (selection); + QVBoxLayout *layout = new QVBoxLayout; - layout->setContentsMargins (QMargins (0, 0, 0, 0)); - mBottom = new QWidget(this); - QStackedLayout *bottmLayout = new QStackedLayout(mBottom); - bottmLayout->setContentsMargins (0, 0, 0, 0); - QStatusBar *statusBar = new QStatusBar(mBottom); - mStatus = new QLabel(mBottom); - statusBar->addWidget (mStatus); - bottmLayout->addWidget (statusBar); - mBottom->setLayout (bottmLayout); + layout->addWidget (mEditor = new ScriptEdit (mDocument, ScriptHighlighter::Mode_General, this), 2); - layout->addWidget (mBottom, 0); - layout->insertWidget (0, mEditor = new ScriptEdit (mDocument, ScriptHighlighter::Mode_General, this), 2); - - QWidget *widget = new QWidget; + QWidget *widget = new QWidget (this);; widget->setLayout (layout); setWidget (widget); @@ -54,6 +48,25 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: mEditor->setPlainText (mModel->data (mModel->getModelIndex (id.getId(), mColumn)).toString()); + // buttons + mButtons = new RecordButtonBar (id, *mModel, 0, &mCommandDispatcher, this); + + layout->addWidget (mButtons); + + // status bar + QStatusBar *statusBar = new QStatusBar(mBottom); + mStatus = new QLabel(mBottom); + statusBar->addWidget (mStatus); + + mBottom = new QWidget(this); + QStackedLayout *bottmLayout = new QStackedLayout(mBottom); + bottmLayout->setContentsMargins (0, 0, 0, 0); + bottmLayout->addWidget (statusBar); + mBottom->setLayout (bottmLayout); + + layout->addWidget (mBottom, 0); + + // signals connect (mEditor, SIGNAL (textChanged()), this, SLOT (textChanged())); connect (mModel, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), @@ -62,6 +75,11 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: connect (mModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), this, SLOT (rowsAboutToBeRemoved (const QModelIndex&, int, int))); + connect (mButtons, SIGNAL (switchToRow (int)), this, SLOT (switchToRow (int))); + + connect (this, SIGNAL (universalIdChanged (const CSMWorld::UniversalId&)), + mButtons, SLOT (universalIdChanged (const CSMWorld::UniversalId&))); + updateStatusBar(); connect(mEditor, SIGNAL(cursorPositionChanged()), this, SLOT(updateStatusBar())); } @@ -78,6 +96,8 @@ void CSVWorld::ScriptSubView::updateUserSetting (const QString& name, const QStr { mEditor->setMonoFont(value.at(0).toStdString() == "true"); } + + mButtons->updateUserSetting (name, value); } void CSVWorld::ScriptSubView::updateStatusBar () @@ -93,6 +113,8 @@ void CSVWorld::ScriptSubView::updateStatusBar () void CSVWorld::ScriptSubView::setEditLock (bool locked) { mEditor->setReadOnly (locked); + mButtons->setEditLock (locked); + mCommandDispatcher.setEditLock (locked); } void CSVWorld::ScriptSubView::useHint (const std::string& hint) @@ -159,3 +181,14 @@ void CSVWorld::ScriptSubView::rowsAboutToBeRemoved (const QModelIndex& parent, i emit closeRequest(); } +void CSVWorld::ScriptSubView::switchToRow (int row) +{ + int idColumn = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Id); + std::string id = mModel->data (mModel->index (row, idColumn)).toString().toUtf8().constData(); + setUniversalId (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Script, id)); + + mEditor->setPlainText (mModel->data (mModel->index (row, mColumn)).toString()); + + std::vector selection (1, id); + mCommandDispatcher.setSelection (selection); +} diff --git a/apps/opencs/view/world/scriptsubview.hpp b/apps/opencs/view/world/scriptsubview.hpp index 1c6474e542..0479e6ad8c 100644 --- a/apps/opencs/view/world/scriptsubview.hpp +++ b/apps/opencs/view/world/scriptsubview.hpp @@ -1,6 +1,8 @@ #ifndef CSV_WORLD_SCRIPTSUBVIEW_H #define CSV_WORLD_SCRIPTSUBVIEW_H +#include "../../model/world/commanddispatcher.hpp" + #include "../doc/subview.hpp" class QModelIndex; @@ -19,6 +21,7 @@ namespace CSMWorld namespace CSVWorld { class ScriptEdit; + class RecordButtonBar; class ScriptSubView : public CSVDoc::SubView { @@ -30,6 +33,8 @@ namespace CSVWorld int mColumn; QWidget *mBottom; QLabel *mStatus; + RecordButtonBar *mButtons; + CSMWorld::CommandDispatcher mCommandDispatcher; public: @@ -52,6 +57,8 @@ namespace CSVWorld private slots: void updateStatusBar(); + + void switchToRow (int row); }; } From 749eff5259269a3fced49098ca39517c06f6a582 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 13 Jul 2015 09:42:16 +0200 Subject: [PATCH 02/19] renaming a few user settings categories --- apps/opencs/model/settings/usersettings.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 1bfc6e85ba..11fc8bfebf 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -162,7 +162,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() ritd->setDeclaredValues (values); } - declareSection ("table-input", "Table Input"); + declareSection ("table-input", "ID Tables"); { QString inPlaceEdit ("Edit in Place"); QString editRecord ("Edit Record"); @@ -217,7 +217,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() jumpToAdded->setDeclaredValues (jumpValues); } - declareSection ("report-input", "Report Input"); + declareSection ("report-input", "Reports"); { QString none ("None"); QString edit ("Edit"); @@ -257,7 +257,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() shiftCtrlDoubleClick->setDefaultValue (none); shiftCtrlDoubleClick->setToolTip ("Action on shift control double click in report table:

" + toolTip); } - + declareSection ("search", "Search & Replace"); { Setting *before = createSetting (Type_SpinBox, "char-before", @@ -299,7 +299,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() QStringList modes; modes << "Ignore" << modeNormal << "Strict"; - + Setting *warnings = createSetting (Type_ComboBox, "warnings", "Warning Mode"); warnings->setDeclaredValues (modes); @@ -309,7 +309,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() "

  • Normal: Report warning as a warning
  • " "
  • Strict: Promote warning to an error
  • " ""); - + Setting *formatInt = createSetting (Type_LineEdit, "colour-int", "Highlight Colour: Int"); formatInt->setDefaultValues (QStringList() << "Dark magenta"); formatInt->setToolTip ("(Default: Green) Use one of the following formats:" + tooltip); @@ -346,7 +346,7 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() 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: From fc6c14614b9277e833ac5a6dc18640c2b1b22655 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 13 Jul 2015 12:52:18 +0200 Subject: [PATCH 03/19] added user settings option to toggle toolbars in single-record subviews --- apps/opencs/model/settings/usersettings.cpp | 9 +++ apps/opencs/view/world/dialoguesubview.cpp | 86 ++++++++++++++------- apps/opencs/view/world/dialoguesubview.hpp | 16 ++-- apps/opencs/view/world/scriptsubview.cpp | 63 ++++++++++----- apps/opencs/view/world/scriptsubview.hpp | 8 ++ 5 files changed, 131 insertions(+), 51 deletions(-) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 11fc8bfebf..673db4057a 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -217,6 +217,12 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() jumpToAdded->setDeclaredValues (jumpValues); } + declareSection ("dialogues", "ID Dialogues"); + { + Setting *toolbar = createSetting (Type_CheckBox, "toolbar", "Show toolbar"); + toolbar->setDefaultValue ("true"); + } + declareSection ("report-input", "Reports"); { QString none ("None"); @@ -310,6 +316,9 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() "
  • Strict: Promote warning to an error
  • " ""); + Setting *toolbar = createSetting (Type_CheckBox, "toolbar", "Show toolbar"); + toolbar->setDefaultValue ("true"); + Setting *formatInt = createSetting (Type_LineEdit, "colour-int", "Highlight Colour: Int"); formatInt->setDefaultValues (QStringList() << "Dark magenta"); formatInt->setToolTip ("(Default: Green) Use one of the following formats:" + tooltip); diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index ed50b81cd7..edd9cc1e28 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -31,6 +31,7 @@ #include "../../model/world/idtree.hpp" #include "../../model/world/commands.hpp" #include "../../model/doc/document.hpp" +#include "../../model/settings/usersettings.hpp" #include "../widget/coloreditor.hpp" #include "../widget/droplineedit.hpp" @@ -66,7 +67,7 @@ void CSVWorld::NotEditableSubDelegate::setEditorData (QWidget* editor, const QMo CSMWorld::Columns::ColumnId columnId = static_cast ( mTable->getColumnId (index.column())); - + if (QVariant::String == v.type()) { label->setText(v.toString()); @@ -75,7 +76,7 @@ void CSVWorld::NotEditableSubDelegate::setEditorData (QWidget* editor, const QMo { int data = v.toInt(); std::vector enumNames (CSMWorld::Columns::getEnums (columnId)); - + label->setText(QString::fromUtf8(enumNames.at(data).c_str())); } else @@ -324,11 +325,11 @@ CSVWorld::IdContextMenu::IdContextMenu(QWidget *widget, CSMWorld::ColumnBase::Di Q_ASSERT(mWidget != NULL); Q_ASSERT(CSMWorld::ColumnBase::isId(display)); Q_ASSERT(mIdType != CSMWorld::UniversalId::Type_None); - + mWidget->setContextMenuPolicy(Qt::CustomContextMenu); - connect(mWidget, - SIGNAL(customContextMenuRequested(const QPoint &)), - this, + connect(mWidget, + SIGNAL(customContextMenuRequested(const QPoint &)), + this, SLOT(showContextMenu(const QPoint &))); mEditIdAction = new QAction(this); @@ -352,7 +353,7 @@ void CSVWorld::IdContextMenu::excludeId(const std::string &id) QString CSVWorld::IdContextMenu::getWidgetValue() const { - QLineEdit *lineEdit = qobject_cast(mWidget); + QLineEdit *lineEdit = qobject_cast(mWidget); QLabel *label = qobject_cast(mWidget); QString value = ""; @@ -411,7 +412,7 @@ void CSVWorld::IdContextMenu::showContextMenu(const QPoint &pos) { removeEditIdActionFromMenu(); } - + if (!mContextMenu->actions().isEmpty()) { mContextMenu->exec(mWidget->mapToGlobal(pos)); @@ -588,9 +589,9 @@ void CSVWorld::EditWidget::remake(int row) tablesLayout->addWidget(label); tablesLayout->addWidget(table); - connect(table, - SIGNAL(editRequest(const CSMWorld::UniversalId &, const std::string &)), - this, + connect(table, + SIGNAL(editRequest(const CSMWorld::UniversalId &, const std::string &)), + this, SIGNAL(editIdRequest(const CSMWorld::UniversalId &, const std::string &))); } else if (!(flags & CSMWorld::ColumnBase::Flag_Dialogue_List)) @@ -830,9 +831,28 @@ void CSVWorld::SimpleDialogueSubView::updateCurrentId() } +void CSVWorld::DialogueSubView::addButtonBar() +{ + if (mButtons) + return; + + mButtons = new RecordButtonBar (getUniversalId(), getTable(), mBottom, + &getCommandDispatcher(), this); + + getMainLayout().insertWidget (1, mButtons); + + // connections + 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&))); +} + CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, const CreatorFactoryBase& creatorFactory, bool sorting) -: SimpleDialogueSubView (id, document) +: SimpleDialogueSubView (id, document), mButtons (0) { // bottom box mBottom = new TableBottomBox (creatorFactory, document, id, this); @@ -843,32 +863,44 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, this, SLOT (requestFocus (const std::string&))); // button bar - mButtons = new RecordButtonBar (id, getTable(), mBottom, - &getCommandDispatcher(), this); + if (CSMSettings::UserSettings::instance().setting ("dialogues/toolbar", QString("true")) == "true") + addButtonBar(); // layout - getMainLayout().addWidget (mButtons); getMainLayout().addWidget (mBottom); - - // connections - 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&))); } void CSVWorld::DialogueSubView::setEditLock (bool locked) { SimpleDialogueSubView::setEditLock (locked); - mButtons->setEditLock (locked); + + if (mButtons) + mButtons->setEditLock (locked); } void CSVWorld::DialogueSubView::updateUserSetting (const QString& name, const QStringList& value) { SimpleDialogueSubView::updateUserSetting (name, value); - mButtons->updateUserSetting (name, value); + + if (name=="dialogues/toolbar") + { + if (value.at(0)==QString ("true")) + { + addButtonBar(); + } + else + { + if (mButtons) + { + getMainLayout().removeWidget (mButtons); + delete mButtons; + mButtons = 0; + } + } + } + + if (mButtons) + mButtons->updateUserSetting (name, value); } void CSVWorld::DialogueSubView::showPreview () @@ -908,7 +940,7 @@ void CSVWorld::DialogueSubView::switchToRow (int row) setUniversalId (CSMWorld::UniversalId (type, id)); updateCurrentId(); - + getEditWidget().remake (row); int stateColumn = getTable().findColumnIndex (CSMWorld::Columns::ColumnId_Modification); @@ -923,5 +955,5 @@ void CSVWorld::DialogueSubView::requestFocus (const std::string& id) QModelIndex index = getTable().getModelIndex (id, 0); if (index.isValid()) - switchToRow (index.row()); + switchToRow (index.row()); } diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index d82936e459..2ae0f97203 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -195,8 +195,8 @@ namespace CSVWorld CSMDoc::Document& mDocument; std::vector mNestedModels; //Plain, raw C pointers, deleted in the dtor - void createEditorContextMenu(QWidget *editor, - CSMWorld::ColumnBase::Display display, + void createEditorContextMenu(QWidget *editor, + CSMWorld::ColumnBase::Display display, int currentRow) const; public: @@ -236,7 +236,7 @@ namespace CSVWorld void updateCurrentId(); bool isLocked() const; - + public: SimpleDialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); @@ -256,10 +256,14 @@ namespace CSVWorld class DialogueSubView : public SimpleDialogueSubView { Q_OBJECT - + TableBottomBox* mBottom; RecordButtonBar *mButtons; + private: + + void addButtonBar(); + public: DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, @@ -268,14 +272,14 @@ namespace CSVWorld virtual void setEditLock (bool locked); virtual void updateUserSetting (const QString& name, const QStringList& value); - + private slots: void showPreview(); void viewRecord(); - void switchToRow (int row); + void switchToRow (int row); void requestFocus (const std::string& id); }; diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index dc079c3a9f..0f5d5014a8 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -17,19 +17,32 @@ #include "scriptedit.hpp" #include "recordbuttonbar.hpp" +void CSVWorld::ScriptSubView::addButtonBar() +{ + if (mButtons) + return; + + mButtons = new RecordButtonBar (getUniversalId(), *mModel, 0, &mCommandDispatcher, this); + + mLayout.insertWidget (1, mButtons); + + connect (mButtons, SIGNAL (switchToRow (int)), this, SLOT (switchToRow (int))); + + connect (this, SIGNAL (universalIdChanged (const CSMWorld::UniversalId&)), + mButtons, SLOT (universalIdChanged (const CSMWorld::UniversalId&))); +} + CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) -: SubView (id), mDocument (document), mColumn (-1), mBottom(0), mStatus(0), +: SubView (id), mDocument (document), mColumn (-1), mBottom(0), mStatus(0), mButtons (0), mCommandDispatcher (document, CSMWorld::UniversalId::getParentType (id.getType())) { std::vector selection (1, id.getId()); mCommandDispatcher.setSelection (selection); - QVBoxLayout *layout = new QVBoxLayout; - - layout->addWidget (mEditor = new ScriptEdit (mDocument, ScriptHighlighter::Mode_General, this), 2); + mLayout.addWidget (mEditor = new ScriptEdit (mDocument, ScriptHighlighter::Mode_General, this), 2); QWidget *widget = new QWidget (this);; - widget->setLayout (layout); + widget->setLayout (&mLayout); setWidget (widget); mModel = &dynamic_cast ( @@ -49,9 +62,8 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: mEditor->setPlainText (mModel->data (mModel->getModelIndex (id.getId(), mColumn)).toString()); // buttons - mButtons = new RecordButtonBar (id, *mModel, 0, &mCommandDispatcher, this); - - layout->addWidget (mButtons); + if (CSMSettings::UserSettings::instance().setting ("script-editor/toolbar", QString("true")) == "true") + addButtonBar(); // status bar QStatusBar *statusBar = new QStatusBar(mBottom); @@ -64,7 +76,7 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: bottmLayout->addWidget (statusBar); mBottom->setLayout (bottmLayout); - layout->addWidget (mBottom, 0); + mLayout.addWidget (mBottom, 0); // signals connect (mEditor, SIGNAL (textChanged()), this, SLOT (textChanged())); @@ -75,11 +87,6 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: connect (mModel, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), this, SLOT (rowsAboutToBeRemoved (const QModelIndex&, int, int))); - connect (mButtons, SIGNAL (switchToRow (int)), this, SLOT (switchToRow (int))); - - connect (this, SIGNAL (universalIdChanged (const CSMWorld::UniversalId&)), - mButtons, SLOT (universalIdChanged (const CSMWorld::UniversalId&))); - updateStatusBar(); connect(mEditor, SIGNAL(cursorPositionChanged()), this, SLOT(updateStatusBar())); } @@ -88,16 +95,33 @@ void CSVWorld::ScriptSubView::updateUserSetting (const QString& name, const QStr { if (name == "script-editor/show-linenum") { - std::string showLinenum = value.at(0).toStdString(); + std::string showLinenum = value.at(0).toUtf8().constData(); mEditor->showLineNum(showLinenum == "true"); mBottom->setVisible(showLinenum == "true"); } else if (name == "script-editor/mono-font") { - mEditor->setMonoFont(value.at(0).toStdString() == "true"); + mEditor->setMonoFont (value.at(0)==QString ("true")); + } + else if (name=="script-editor/toolbar") + { + if (value.at(0)==QString ("true")) + { + addButtonBar(); + } + else + { + if (mButtons) + { + mLayout.removeWidget (mButtons); + delete mButtons; + mButtons = 0; + } + } } - mButtons->updateUserSetting (name, value); + if (mButtons) + mButtons->updateUserSetting (name, value); } void CSVWorld::ScriptSubView::updateStatusBar () @@ -113,7 +137,10 @@ void CSVWorld::ScriptSubView::updateStatusBar () void CSVWorld::ScriptSubView::setEditLock (bool locked) { mEditor->setReadOnly (locked); - mButtons->setEditLock (locked); + + if (mButtons) + mButtons->setEditLock (locked); + mCommandDispatcher.setEditLock (locked); } diff --git a/apps/opencs/view/world/scriptsubview.hpp b/apps/opencs/view/world/scriptsubview.hpp index 0479e6ad8c..370754ebe7 100644 --- a/apps/opencs/view/world/scriptsubview.hpp +++ b/apps/opencs/view/world/scriptsubview.hpp @@ -1,12 +1,15 @@ #ifndef CSV_WORLD_SCRIPTSUBVIEW_H #define CSV_WORLD_SCRIPTSUBVIEW_H +#include + #include "../../model/world/commanddispatcher.hpp" #include "../doc/subview.hpp" class QModelIndex; class QLabel; +class QVBoxLayout; namespace CSMDoc { @@ -35,6 +38,11 @@ namespace CSVWorld QLabel *mStatus; RecordButtonBar *mButtons; CSMWorld::CommandDispatcher mCommandDispatcher; + QVBoxLayout mLayout; + + private: + + void addButtonBar(); public: From 2202973c2462b9299480c9106904383a113fb89d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 14 Jul 2015 10:05:45 +0200 Subject: [PATCH 04/19] replaced the script subview status bar with a bottom box (including a status bar) --- apps/opencs/view/world/dialoguesubview.cpp | 2 -- apps/opencs/view/world/scriptsubview.cpp | 33 +++++++++----------- apps/opencs/view/world/scriptsubview.hpp | 6 ++-- apps/opencs/view/world/tablebottombox.cpp | 36 ++++++++++++++++++---- apps/opencs/view/world/tablebottombox.hpp | 13 ++++++-- 5 files changed, 59 insertions(+), 31 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index edd9cc1e28..5a44708c19 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -857,8 +857,6 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, // bottom box mBottom = new TableBottomBox (creatorFactory, document, id, this); - mBottom->setSizePolicy (QSizePolicy::Ignored, QSizePolicy::Fixed); - connect (mBottom, SIGNAL (requestFocus (const std::string&)), this, SLOT (requestFocus (const std::string&))); diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index 0f5d5014a8..f65f772856 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -4,7 +4,6 @@ #include #include -#include #include "../../model/doc/document.hpp" #include "../../model/world/universalid.hpp" @@ -16,6 +15,8 @@ #include "scriptedit.hpp" #include "recordbuttonbar.hpp" +#include "tablebottombox.hpp" +#include "genericcreator.hpp" void CSVWorld::ScriptSubView::addButtonBar() { @@ -33,7 +34,7 @@ void CSVWorld::ScriptSubView::addButtonBar() } CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) -: SubView (id), mDocument (document), mColumn (-1), mBottom(0), mStatus(0), mButtons (0), +: SubView (id), mDocument (document), mColumn (-1), mBottom(0), mButtons (0), mCommandDispatcher (document, CSMWorld::UniversalId::getParentType (id.getType())) { std::vector selection (1, id.getId()); @@ -65,18 +66,13 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: if (CSMSettings::UserSettings::instance().setting ("script-editor/toolbar", QString("true")) == "true") addButtonBar(); - // status bar - QStatusBar *statusBar = new QStatusBar(mBottom); - mStatus = new QLabel(mBottom); - statusBar->addWidget (mStatus); + // bottom box + mBottom = new TableBottomBox (CreatorFactory(), document, id, this); - mBottom = new QWidget(this); - QStackedLayout *bottmLayout = new QStackedLayout(mBottom); - bottmLayout->setContentsMargins (0, 0, 0, 0); - bottmLayout->addWidget (statusBar); - mBottom->setLayout (bottmLayout); + connect (mBottom, SIGNAL (requestFocus (const std::string&)), + this, SLOT (requestFocus (const std::string&))); - mLayout.addWidget (mBottom, 0); + mLayout.addWidget (mBottom); // signals connect (mEditor, SIGNAL (textChanged()), this, SLOT (textChanged())); @@ -124,14 +120,15 @@ void CSVWorld::ScriptSubView::updateUserSetting (const QString& name, const QStr mButtons->updateUserSetting (name, value); } +void CSVWorld::ScriptSubView::setStatusBar (bool show) +{ + mBottom->setStatusBar (show); +} + void CSVWorld::ScriptSubView::updateStatusBar () { - std::ostringstream stream; - - stream << "(" << mEditor->textCursor().blockNumber() + 1 << ", " - << mEditor->textCursor().columnNumber() + 1 << ")"; - - mStatus->setText (QString::fromUtf8 (stream.str().c_str())); + mBottom->positionChanged (mEditor->textCursor().blockNumber() + 1, + mEditor->textCursor().columnNumber() + 1); } void CSVWorld::ScriptSubView::setEditLock (bool locked) diff --git a/apps/opencs/view/world/scriptsubview.hpp b/apps/opencs/view/world/scriptsubview.hpp index 370754ebe7..09f7907ee9 100644 --- a/apps/opencs/view/world/scriptsubview.hpp +++ b/apps/opencs/view/world/scriptsubview.hpp @@ -25,6 +25,7 @@ namespace CSVWorld { class ScriptEdit; class RecordButtonBar; + class TableBottomBox; class ScriptSubView : public CSVDoc::SubView { @@ -34,8 +35,7 @@ namespace CSVWorld CSMDoc::Document& mDocument; CSMWorld::IdTable *mModel; int mColumn; - QWidget *mBottom; - QLabel *mStatus; + TableBottomBox *mBottom; RecordButtonBar *mButtons; CSMWorld::CommandDispatcher mCommandDispatcher; QVBoxLayout mLayout; @@ -54,6 +54,8 @@ namespace CSVWorld virtual void updateUserSetting (const QString& name, const QStringList& value); + virtual void setStatusBar (bool show); + public slots: void textChanged(); diff --git a/apps/opencs/view/world/tablebottombox.cpp b/apps/opencs/view/world/tablebottombox.cpp index dc3a6cc764..12226450b0 100644 --- a/apps/opencs/view/world/tablebottombox.cpp +++ b/apps/opencs/view/world/tablebottombox.cpp @@ -35,15 +35,23 @@ void CSVWorld::TableBottomBox::updateStatus() } } + if (mHasPosition) + { + if (!first) + stream << " -- "; + + stream << "(" << mRow << ", " << mColumn << ")"; + } + mStatus->setText (QString::fromUtf8 (stream.str().c_str())); } } -CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFactory, - CSMDoc::Document& document, - const CSMWorld::UniversalId& id, +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), mCreating (false), mHasPosition (false) { for (int i=0; i<4; ++i) mStatusCount[i] = 0; @@ -74,6 +82,8 @@ CSVWorld::TableBottomBox::TableBottomBox (const CreatorFactoryBase& creatorFacto connect (mCreator, SIGNAL (requestFocus (const std::string&)), this, SIGNAL (requestFocus (const std::string&))); } + + setSizePolicy (QSizePolicy::Ignored, QSizePolicy::Fixed); } void CSVWorld::TableBottomBox::setEditLock (bool locked) @@ -152,6 +162,20 @@ void CSVWorld::TableBottomBox::tableSizeChanged (int size, int deleted, int modi updateStatus(); } +void CSVWorld::TableBottomBox::positionChanged (int row, int column) +{ + mRow = row; + mColumn = column; + mHasPosition = true; + updateStatus(); +} + +void CSVWorld::TableBottomBox::noMorePosition() +{ + mHasPosition = false; + updateStatus(); +} + void CSVWorld::TableBottomBox::createRequest() { mCreator->reset(); @@ -162,8 +186,8 @@ void CSVWorld::TableBottomBox::createRequest() mCreator->focus(); } -void CSVWorld::TableBottomBox::cloneRequest(const std::string& id, - const CSMWorld::UniversalId::Type type) +void CSVWorld::TableBottomBox::cloneRequest(const std::string& id, + const CSMWorld::UniversalId::Type type) { mCreator->reset(); mCreator->cloneMode(id, type); diff --git a/apps/opencs/view/world/tablebottombox.hpp b/apps/opencs/view/world/tablebottombox.hpp index a7d009c42d..6e68553bc8 100644 --- a/apps/opencs/view/world/tablebottombox.hpp +++ b/apps/opencs/view/world/tablebottombox.hpp @@ -30,6 +30,9 @@ namespace CSVWorld Creator *mCreator; bool mCreating; QStackedLayout *mLayout; + bool mHasPosition; + int mRow; + int mColumn; private: @@ -41,9 +44,9 @@ namespace CSVWorld public: - TableBottomBox (const CreatorFactoryBase& creatorFactory, - CSMDoc::Document& document, - const CSMWorld::UniversalId& id, + TableBottomBox (const CreatorFactoryBase& creatorFactory, + CSMDoc::Document& document, + const CSMWorld::UniversalId& id, QWidget *parent = 0); virtual ~TableBottomBox(); @@ -77,6 +80,10 @@ namespace CSVWorld /// \param deleted Number of deleted records /// \param modified Number of added and modified records + void positionChanged (int row, int column); + + void noMorePosition(); + void createRequest(); void cloneRequest(const std::string& id, const CSMWorld::UniversalId::Type type); From 0860c27b039465e4505f5211a9bcbb9ddedf773e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 14 Jul 2015 11:49:41 +0200 Subject: [PATCH 05/19] improving consistency of subview layouts --- apps/opencs/view/tools/searchsubview.cpp | 20 +++++++++----------- apps/opencs/view/world/previewsubview.cpp | 2 -- apps/opencs/view/world/scenesubview.cpp | 2 -- apps/opencs/view/world/tablesubview.cpp | 3 --- 4 files changed, 9 insertions(+), 18 deletions(-) diff --git a/apps/opencs/view/tools/searchsubview.cpp b/apps/opencs/view/tools/searchsubview.cpp index dc670af40a..8b35db6aed 100644 --- a/apps/opencs/view/tools/searchsubview.cpp +++ b/apps/opencs/view/tools/searchsubview.cpp @@ -16,7 +16,7 @@ void CSVTools::SearchSubView::replace (bool selection) { if (mLocked) return; - + std::vector indices = mTable->getReplaceIndices (selection); std::string replace = mSearchBox.getReplaceText(); @@ -29,7 +29,7 @@ void CSVTools::SearchSubView::replace (bool selection) CSMTools::Search search (mSearch); CSMWorld::IdTableBase *currentTable = 0; - + // We are running through the indices in reverse order to avoid messing up multiple results // in a single string. for (std::vector::const_reverse_iterator iter (indices.rbegin()); iter!=indices.rend(); ++iter) @@ -46,7 +46,7 @@ void CSVTools::SearchSubView::replace (bool selection) search.configure (table); currentTable = table; } - + std::string hint = model.getHint (*iter); if (search.verify (mDocument, table, id, hint)) @@ -63,7 +63,7 @@ void CSVTools::SearchSubView::replace (bool selection) void CSVTools::SearchSubView::showEvent (QShowEvent *event) { CSVDoc::SubView::showEvent (event); - mSearchBox.focus(); + mSearchBox.focus(); } CSVTools::SearchSubView::SearchSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) @@ -71,25 +71,23 @@ CSVTools::SearchSubView::SearchSubView (const CSMWorld::UniversalId& id, CSMDoc: { QVBoxLayout *layout = new QVBoxLayout; - layout->setContentsMargins (QMargins (0, 0, 0, 0)); - layout->addWidget (&mSearchBox); - + layout->addWidget (mTable = new ReportTable (document, id, true), 2); QWidget *widget = new QWidget; - + widget->setLayout (layout); setWidget (widget); stateChanged (document.getState(), &document); - + connect (mTable, SIGNAL (editRequest (const CSMWorld::UniversalId&, const std::string&)), SIGNAL (focusId (const CSMWorld::UniversalId&, const std::string&))); connect (mTable, SIGNAL (replaceRequest()), this, SLOT (replaceRequest())); - + connect (&document, SIGNAL (stateChanged (int, CSMDoc::Document *)), this, SLOT (stateChanged (int, CSMDoc::Document *))); @@ -124,7 +122,7 @@ void CSVTools::SearchSubView::startSearch (const CSMTools::Search& search) mSearch = search; mSearch.setPadding (paddingBefore, paddingAfter); - + mTable->clear(); mDocument.runSearch (getUniversalId(), mSearch); } diff --git a/apps/opencs/view/world/previewsubview.cpp b/apps/opencs/view/world/previewsubview.cpp index 1c2d6b95c7..756e79fe6f 100644 --- a/apps/opencs/view/world/previewsubview.cpp +++ b/apps/opencs/view/world/previewsubview.cpp @@ -13,8 +13,6 @@ CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDo { QHBoxLayout *layout = new QHBoxLayout; - layout->setContentsMargins (QMargins (0, 0, 0, 0)); - if (document.getData().getReferenceables().searchId (id.getId())==-1) { std::string referenceableId = diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 397d249296..b7a795e230 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -31,8 +31,6 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D { QVBoxLayout *layout = new QVBoxLayout; - layout->setContentsMargins (QMargins (0, 0, 0, 0)); - layout->addWidget (mBottom = new TableBottomBox (NullCreatorFactory(), document, id, this), 0); mLayout->setContentsMargins (QMargins (0, 0, 0, 0)); diff --git a/apps/opencs/view/world/tablesubview.cpp b/apps/opencs/view/world/tablesubview.cpp index 75671a50c4..e2c9e2fb14 100644 --- a/apps/opencs/view/world/tablesubview.cpp +++ b/apps/opencs/view/world/tablesubview.cpp @@ -23,8 +23,6 @@ CSVWorld::TableSubView::TableSubView (const CSMWorld::UniversalId& id, CSMDoc::D { QVBoxLayout *layout = new QVBoxLayout; - layout->setContentsMargins (QMargins (0, 0, 0, 0)); - layout->addWidget (mBottom = new TableBottomBox (creatorFactory, document, id, this), 0); @@ -166,4 +164,3 @@ bool CSVWorld::TableSubView::eventFilter (QObject* object, QEvent* event) } return false; } - From cf1fb76bb4cdb3e08f8b4a71e682681a811fe64b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 14 Jul 2015 13:34:13 +0200 Subject: [PATCH 06/19] fixed deleted button sensitivity state --- apps/opencs/view/world/recordbuttonbar.cpp | 29 +++++++++++----------- 1 file changed, 14 insertions(+), 15 deletions(-) diff --git a/apps/opencs/view/world/recordbuttonbar.cpp b/apps/opencs/view/world/recordbuttonbar.cpp index 63c0dd0a18..9cae0d0c9d 100644 --- a/apps/opencs/view/world/recordbuttonbar.cpp +++ b/apps/opencs/view/world/recordbuttonbar.cpp @@ -17,18 +17,17 @@ void CSVWorld::RecordButtonBar::updateModificationButtons() mCloneButton->setDisabled (createAndDeleteDisabled); mAddButton->setDisabled (createAndDeleteDisabled); - mDeleteButton->setDisabled (createAndDeleteDisabled); bool commandDisabled = !mCommandDispatcher || mLocked; - + mRevertButton->setDisabled (commandDisabled); - mDeleteButton->setDisabled (commandDisabled); + mDeleteButton->setDisabled (commandDisabled || createAndDeleteDisabled); } void CSVWorld::RecordButtonBar::updatePrevNextButtons() { int rows = mTable.rowCount(); - + if (rows<=1) { mPrevButton->setDisabled (true); @@ -62,12 +61,12 @@ CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id, mPrevButton->setIcon(QIcon(":/go-previous.png")); mPrevButton->setToolTip ("Switch to previous record"); buttonsLayout->addWidget (mPrevButton, 0); - + mNextButton = new QToolButton (this); mNextButton->setIcon(QIcon(":/go-next.png")); mNextButton->setToolTip ("Switch to next record"); buttonsLayout->addWidget (mNextButton, 1); - + buttonsLayout->addStretch(2); // optional buttons of the right section @@ -94,22 +93,22 @@ CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id, mCloneButton->setIcon(QIcon(":/edit-clone.png")); mCloneButton->setToolTip ("Clone record"); buttonsLayout->addWidget(mCloneButton); - + mAddButton = new QToolButton (this); mAddButton->setIcon(QIcon(":/add.png")); mAddButton->setToolTip ("Add new record"); buttonsLayout->addWidget(mAddButton); - + mDeleteButton = new QToolButton (this); mDeleteButton->setIcon(QIcon(":/edit-delete.png")); mDeleteButton->setToolTip ("Delete record"); buttonsLayout->addWidget(mDeleteButton); - + mRevertButton = new QToolButton (this); mRevertButton->setIcon(QIcon(":/edit-undo.png")); mRevertButton->setToolTip ("Revert record"); buttonsLayout->addWidget(mRevertButton); - + setLayout (buttonsLayout); // connections @@ -132,7 +131,7 @@ CSVWorld::RecordButtonBar::RecordButtonBar (const CSMWorld::UniversalId& id, this, SLOT (rowNumberChanged (const QModelIndex&, int, int))); connect (&mTable, SIGNAL (rowsRemoved (const QModelIndex&, int, int)), this, SLOT (rowNumberChanged (const QModelIndex&, int, int))); - + updateModificationButtons(); updatePrevNextButtons(); } @@ -170,7 +169,7 @@ void CSVWorld::RecordButtonBar::cloneRequest() } void CSVWorld::RecordButtonBar::nextId() -{ +{ int newRow = mTable.getModelIndex (mId.getId(), 0).row() + 1; if (newRow >= mTable.rowCount()) @@ -180,8 +179,8 @@ void CSVWorld::RecordButtonBar::nextId() newRow = 0; else return; - } - + } + emit switchToRow (newRow); } @@ -197,7 +196,7 @@ void CSVWorld::RecordButtonBar::prevId() else return; } - + emit switchToRow (newRow); } From df027b3498f1730cfda5daed06052c04a64456d9 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 14 Jul 2015 13:52:48 +0200 Subject: [PATCH 07/19] hooked up script subview buttons to bottom box (enables add and clone) --- apps/opencs/view/world/scriptsubview.cpp | 15 +++++++++------ apps/opencs/view/world/scriptsubview.hpp | 2 ++ 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index f65f772856..181400c888 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -23,7 +23,7 @@ void CSVWorld::ScriptSubView::addButtonBar() if (mButtons) return; - mButtons = new RecordButtonBar (getUniversalId(), *mModel, 0, &mCommandDispatcher, this); + mButtons = new RecordButtonBar (getUniversalId(), *mModel, mBottom, &mCommandDispatcher, this); mLayout.insertWidget (1, mButtons); @@ -61,16 +61,14 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: throw std::logic_error ("Can't find script column"); mEditor->setPlainText (mModel->data (mModel->getModelIndex (id.getId(), mColumn)).toString()); + // bottom box and buttons + mBottom = new TableBottomBox (CreatorFactory(), document, id, this); - // buttons if (CSMSettings::UserSettings::instance().setting ("script-editor/toolbar", QString("true")) == "true") addButtonBar(); - // bottom box - mBottom = new TableBottomBox (CreatorFactory(), document, id, this); - connect (mBottom, SIGNAL (requestFocus (const std::string&)), - this, SLOT (requestFocus (const std::string&))); + this, SLOT (switchToId (const std::string&))); mLayout.addWidget (mBottom); @@ -216,3 +214,8 @@ void CSVWorld::ScriptSubView::switchToRow (int row) std::vector selection (1, id); mCommandDispatcher.setSelection (selection); } + +void CSVWorld::ScriptSubView::switchToId (const std::string& id) +{ + switchToRow (mModel->getModelIndex (id, 0).row()); +} diff --git a/apps/opencs/view/world/scriptsubview.hpp b/apps/opencs/view/world/scriptsubview.hpp index 09f7907ee9..6e5276c682 100644 --- a/apps/opencs/view/world/scriptsubview.hpp +++ b/apps/opencs/view/world/scriptsubview.hpp @@ -69,6 +69,8 @@ namespace CSVWorld void updateStatusBar(); void switchToRow (int row); + + void switchToId (const std::string& id); }; } From 2016ff773fbf0376c28dfaa9df0ff65d47052f84 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 16 Jul 2015 12:36:20 +0200 Subject: [PATCH 08/19] display script errors in script subview --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/world/scripterrortable.cpp | 87 +++++++++++++++++++++ apps/opencs/view/world/scripterrortable.hpp | 45 +++++++++++ apps/opencs/view/world/scriptsubview.cpp | 33 +++++++- apps/opencs/view/world/scriptsubview.hpp | 4 + 5 files changed, 166 insertions(+), 5 deletions(-) create mode 100644 apps/opencs/view/world/scripterrortable.cpp create mode 100644 apps/opencs/view/world/scripterrortable.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 4c7801d461..96e5a5b32d 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 tableeditidaction + dialoguespinbox recordbuttonbar tableeditidaction scripterrortable ) opencs_units_noqt (view/world diff --git a/apps/opencs/view/world/scripterrortable.cpp b/apps/opencs/view/world/scripterrortable.cpp new file mode 100644 index 0000000000..0c97339dc9 --- /dev/null +++ b/apps/opencs/view/world/scripterrortable.cpp @@ -0,0 +1,87 @@ + +#include "scripterrortable.hpp" + +#include + +#include +#include +#include +#include +#include + +#include "../../model/doc/document.hpp" + + +void CSVWorld::ScriptErrorTable::report (const std::string& message, const Compiler::TokenLoc& loc, Type type) +{ + addMessage (message, type==Compiler::ErrorHandler::WarningMessage ? + CSMDoc::Message::Severity_Warning : CSMDoc::Message::Severity_Error, loc.mLine); +} + +void CSVWorld::ScriptErrorTable::report (const std::string& message, Type type) +{ + addMessage (message, type==Compiler::ErrorHandler::WarningMessage ? + CSMDoc::Message::Severity_Warning : CSMDoc::Message::Severity_Error); +} + +void CSVWorld::ScriptErrorTable::addMessage (const std::string& message, + CSMDoc::Message::Severity severity, int line) +{ + int row = rowCount(); + + setRowCount (row+1); + + setItem (row, 0, new QTableWidgetItem ("")); + + if (line!=-1) + { + QTableWidgetItem *item = new QTableWidgetItem; + item->setData (Qt::DisplayRole, line+1); + setItem (row, 1, item); + } + + setItem (row, 2, new QTableWidgetItem (QString::fromUtf8 (message.c_str()))); +} + +CSVWorld::ScriptErrorTable::ScriptErrorTable (const CSMDoc::Document& document, QWidget *parent) +: QTableWidget (parent), mContext (document.getData()) +{ + setColumnCount (3); + + QStringList headers; + headers << "Severity" << "Line" << "Description"; + setHorizontalHeaderLabels (headers); + horizontalHeader()->setStretchLastSection (true); + + Compiler::registerExtensions (mExtensions); + mContext.setExtensions (&mExtensions); +} + +void CSVWorld::ScriptErrorTable::updateUserSetting (const QString& name, const QStringList& value) +{ + +} + +void CSVWorld::ScriptErrorTable::update (const std::string& source) +{ + setRowCount (0); + + try + { + std::istringstream input (source); + + Compiler::Scanner scanner (*this, input, mContext.getExtensions()); + + Compiler::FileParser parser (*this, mContext); + + scanner.scan (parser); + } + catch (const Compiler::SourceException&) + { + // error has already been reported via error handler + } + catch (const std::exception& error) + { + addMessage (error.what(), CSMDoc::Message::Severity_SeriousError); + } +} diff --git a/apps/opencs/view/world/scripterrortable.hpp b/apps/opencs/view/world/scripterrortable.hpp new file mode 100644 index 0000000000..791125c127 --- /dev/null +++ b/apps/opencs/view/world/scripterrortable.hpp @@ -0,0 +1,45 @@ +#ifndef CSV_WORLD_SCRIPTERRORTABLE_H +#define CSV_WORLD_SCRIPTERRORTABLE_H + +#include + +#include +#include + +#include "../../model/world/scriptcontext.hpp" +#include "../../model/doc/messages.hpp" + +namespace CSMDoc +{ + class Document; +} + +namespace CSVWorld +{ + class ScriptErrorTable : public QTableWidget, private Compiler::ErrorHandler + { + Q_OBJECT + + Compiler::Extensions mExtensions; + CSMWorld::ScriptContext mContext; + + virtual void report (const std::string& message, const Compiler::TokenLoc& loc, Type type); + ///< Report error to the user. + + virtual void report (const std::string& message, Type type); + ///< Report a file related error + + void addMessage (const std::string& message, CSMDoc::Message::Severity severity, + int line = -1); + + public: + + ScriptErrorTable (const CSMDoc::Document& document, QWidget *parent = 0); + + void updateUserSetting (const QString& name, const QStringList& value); + + void update (const std::string& source); + }; +} + +#endif diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index 181400c888..d48e647d9b 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -4,6 +4,7 @@ #include #include +#include #include "../../model/doc/document.hpp" #include "../../model/world/universalid.hpp" @@ -17,6 +18,7 @@ #include "recordbuttonbar.hpp" #include "tablebottombox.hpp" #include "genericcreator.hpp" +#include "scripterrortable.hpp" void CSVWorld::ScriptSubView::addButtonBar() { @@ -40,7 +42,16 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: std::vector selection (1, id.getId()); mCommandDispatcher.setSelection (selection); - mLayout.addWidget (mEditor = new ScriptEdit (mDocument, ScriptHighlighter::Mode_General, this), 2); + mMain = new QSplitter (this); + mMain->setOrientation (Qt::Vertical); + mLayout.addWidget (mMain, 2); + + mEditor = new ScriptEdit (mDocument, ScriptHighlighter::Mode_General, this); + mMain->addWidget (mEditor); + mMain->setCollapsible (0, false); + + mErrors = new ScriptErrorTable (document, this); + mMain->addWidget (mErrors); QWidget *widget = new QWidget (this);; widget->setLayout (&mLayout); @@ -60,7 +71,9 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: if (mColumn==-1) throw std::logic_error ("Can't find script column"); - mEditor->setPlainText (mModel->data (mModel->getModelIndex (id.getId(), mColumn)).toString()); + QString source = mModel->data (mModel->getModelIndex (id.getId(), mColumn)).toString(); + + mEditor->setPlainText (source); // bottom box and buttons mBottom = new TableBottomBox (CreatorFactory(), document, id, this); @@ -83,6 +96,8 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: updateStatusBar(); connect(mEditor, SIGNAL(cursorPositionChanged()), this, SLOT(updateStatusBar())); + + mErrors->update (source.toUtf8().constData()); } void CSVWorld::ScriptSubView::updateUserSetting (const QString& name, const QStringList& value) @@ -116,6 +131,8 @@ void CSVWorld::ScriptSubView::updateUserSetting (const QString& name, const QStr if (mButtons) mButtons->updateUserSetting (name, value); + + mErrors->updateUserSetting (name, value); } void CSVWorld::ScriptSubView::setStatusBar (bool show) @@ -173,8 +190,12 @@ void CSVWorld::ScriptSubView::textChanged() ScriptEdit::ChangeLock lock (*mEditor); + QString source = mEditor->toPlainText(); + mDocument.getUndoStack().push (new CSMWorld::ModifyCommand (*mModel, - mModel->getModelIndex (getUniversalId().getId(), mColumn), mEditor->toPlainText())); + mModel->getModelIndex (getUniversalId().getId(), mColumn), source)); + + mErrors->update (source.toUtf8().constData()); } void CSVWorld::ScriptSubView::dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) @@ -189,9 +210,13 @@ void CSVWorld::ScriptSubView::dataChanged (const QModelIndex& topLeft, const QMo if (index.row()>=topLeft.row() && index.row()<=bottomRight.row() && index.column()>=topLeft.column() && index.column()<=bottomRight.column()) { + QString source = mModel->data (index).toString(); + QTextCursor cursor = mEditor->textCursor(); - mEditor->setPlainText (mModel->data (index).toString()); + mEditor->setPlainText (source); mEditor->setTextCursor (cursor); + + mErrors->update (source.toUtf8().constData()); } } diff --git a/apps/opencs/view/world/scriptsubview.hpp b/apps/opencs/view/world/scriptsubview.hpp index 6e5276c682..0b6f4d9239 100644 --- a/apps/opencs/view/world/scriptsubview.hpp +++ b/apps/opencs/view/world/scriptsubview.hpp @@ -10,6 +10,7 @@ class QModelIndex; class QLabel; class QVBoxLayout; +class QSplitter; namespace CSMDoc { @@ -26,6 +27,7 @@ namespace CSVWorld class ScriptEdit; class RecordButtonBar; class TableBottomBox; + class ScriptErrorTable; class ScriptSubView : public CSVDoc::SubView { @@ -39,6 +41,8 @@ namespace CSVWorld RecordButtonBar *mButtons; CSMWorld::CommandDispatcher mCommandDispatcher; QVBoxLayout mLayout; + QSplitter *mMain; + ScriptErrorTable *mErrors; private: From 2d8a78726dbab573041cd97d922a4814bc3471ff Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 16 Jul 2015 14:09:14 +0200 Subject: [PATCH 09/19] improved error reporting --- apps/opencs/view/world/scripterrortable.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/world/scripterrortable.cpp b/apps/opencs/view/world/scripterrortable.cpp index 0c97339dc9..cb793237ae 100644 --- a/apps/opencs/view/world/scripterrortable.cpp +++ b/apps/opencs/view/world/scripterrortable.cpp @@ -14,7 +14,10 @@ void CSVWorld::ScriptErrorTable::report (const std::string& message, const Compiler::TokenLoc& loc, Type type) { - addMessage (message, type==Compiler::ErrorHandler::WarningMessage ? + std::ostringstream stream; + stream << message << " (" << loc.mLiteral << ")"; + + addMessage (stream.str(), type==Compiler::ErrorHandler::WarningMessage ? CSMDoc::Message::Severity_Warning : CSMDoc::Message::Severity_Error, loc.mLine); } From 9b12b4f1e25dff384137a8915ddc460acdbd749e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 16 Jul 2015 14:46:02 +0200 Subject: [PATCH 10/19] refactored mapping from message severity enum to string --- apps/opencs/model/doc/messages.cpp | 16 +++++++++++++++- apps/opencs/model/doc/messages.hpp | 8 +++++--- apps/opencs/model/tools/reportmodel.cpp | 20 +++++++------------- apps/opencs/view/world/scripterrortable.cpp | 2 +- 4 files changed, 28 insertions(+), 18 deletions(-) diff --git a/apps/opencs/model/doc/messages.cpp b/apps/opencs/model/doc/messages.cpp index bd6e808c82..c8d26d39bb 100644 --- a/apps/opencs/model/doc/messages.cpp +++ b/apps/opencs/model/doc/messages.cpp @@ -8,6 +8,20 @@ CSMDoc::Message::Message (const CSMWorld::UniversalId& id, const std::string& me : mId (id), mMessage (message), mHint (hint), mSeverity (severity) {} +std::string CSMDoc::Message::toString (Severity severity) +{ + switch (severity) + { + case CSMDoc::Message::Severity_Info: return "Information"; + case CSMDoc::Message::Severity_Warning: return "Warning"; + case CSMDoc::Message::Severity_Error: return "Error"; + case CSMDoc::Message::Severity_SeriousError: return "Serious Error"; + case CSMDoc::Message::Severity_Default: break; + } + + return ""; +} + CSMDoc::Messages::Messages (Message::Severity default_) : mDefault (default_) @@ -18,7 +32,7 @@ void CSMDoc::Messages::add (const CSMWorld::UniversalId& id, const std::string& { if (severity==Message::Severity_Default) severity = mDefault; - + mMessages.push_back (Message (id, message, hint, severity)); } diff --git a/apps/opencs/model/doc/messages.hpp b/apps/opencs/model/doc/messages.hpp index 86f5feb152..429feae4ec 100644 --- a/apps/opencs/model/doc/messages.hpp +++ b/apps/opencs/model/doc/messages.hpp @@ -21,18 +21,20 @@ namespace CSMDoc // reporting it correctly Severity_Default = 4 }; - + CSMWorld::UniversalId mId; std::string mMessage; std::string mHint; Severity mSeverity; Message(); - + Message (const CSMWorld::UniversalId& id, const std::string& message, const std::string& hint, Severity severity); + + static std::string toString (Severity severity); }; - + class Messages { public: diff --git a/apps/opencs/model/tools/reportmodel.cpp b/apps/opencs/model/tools/reportmodel.cpp index 480691710d..4bf7d1581d 100644 --- a/apps/opencs/model/tools/reportmodel.cpp +++ b/apps/opencs/model/tools/reportmodel.cpp @@ -13,7 +13,7 @@ CSMTools::ReportModel::ReportModel (bool fieldColumn, bool severityColumn) if (severityColumn) mColumnSeverity = index++; - + if (fieldColumn) mColumnField = index++; @@ -46,7 +46,7 @@ QVariant CSMTools::ReportModel::data (const QModelIndex & index, int role) const case Column_Type: return static_cast (mRows.at (index.row()).mId.getType()); - + case Column_Id: { CSMWorld::UniversalId id = mRows.at (index.row()).mId; @@ -56,7 +56,7 @@ QVariant CSMTools::ReportModel::data (const QModelIndex & index, int role) const return QString ("-"); } - + case Column_Hint: return QString::fromUtf8 (mRows.at (index.row()).mHint.c_str()); @@ -85,16 +85,10 @@ QVariant CSMTools::ReportModel::data (const QModelIndex & index, int role) const if (index.column()==mColumnSeverity) { - switch (mRows.at (index.row()).mSeverity) - { - case CSMDoc::Message::Severity_Info: return "Information"; - case CSMDoc::Message::Severity_Warning: return "Warning"; - case CSMDoc::Message::Severity_Error: return "Error"; - case CSMDoc::Message::Severity_SeriousError: return "Serious Error"; - case CSMDoc::Message::Severity_Default: break; - } + return QString::fromUtf8 ( + CSMDoc::Message::toString (mRows.at (index.row()).mSeverity).c_str()); } - + return QVariant(); } @@ -144,7 +138,7 @@ bool CSMTools::ReportModel::removeRows (int row, int count, const QModelIndex& p void CSMTools::ReportModel::add (const CSMDoc::Message& message) { beginInsertRows (QModelIndex(), mRows.size(), mRows.size()); - + mRows.push_back (message); endInsertRows(); diff --git a/apps/opencs/view/world/scripterrortable.cpp b/apps/opencs/view/world/scripterrortable.cpp index cb793237ae..dfa0368244 100644 --- a/apps/opencs/view/world/scripterrortable.cpp +++ b/apps/opencs/view/world/scripterrortable.cpp @@ -34,7 +34,7 @@ void CSVWorld::ScriptErrorTable::addMessage (const std::string& message, setRowCount (row+1); - setItem (row, 0, new QTableWidgetItem ("")); + setItem (row, 0, new QTableWidgetItem (QString::fromUtf8 (CSMDoc::Message::toString (severity).c_str()))); if (line!=-1) { From eab1ec9160674db02c5b701479e86d5acb8c3f43 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 17 Jul 2015 11:52:59 +0200 Subject: [PATCH 11/19] consider script warning settings for script subview --- apps/opencs/view/world/scripterrortable.cpp | 19 +++++++++++++++++-- apps/opencs/view/world/scripterrortable.hpp | 2 ++ 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/world/scripterrortable.cpp b/apps/opencs/view/world/scripterrortable.cpp index dfa0368244..29f1d6820a 100644 --- a/apps/opencs/view/world/scripterrortable.cpp +++ b/apps/opencs/view/world/scripterrortable.cpp @@ -10,7 +10,7 @@ #include #include "../../model/doc/document.hpp" - +#include "../../model/settings/usersettings.hpp" void CSVWorld::ScriptErrorTable::report (const std::string& message, const Compiler::TokenLoc& loc, Type type) { @@ -44,6 +44,18 @@ void CSVWorld::ScriptErrorTable::addMessage (const std::string& message, } setItem (row, 2, new QTableWidgetItem (QString::fromUtf8 (message.c_str()))); + + +} + +void CSVWorld::ScriptErrorTable::setWarningsMode (const QString& value) +{ + if (value=="Ignore") + Compiler::ErrorHandler::setWarningsMode (0); + else if (value=="Normal") + Compiler::ErrorHandler::setWarningsMode (1); + else if (value=="Strict") + Compiler::ErrorHandler::setWarningsMode (2); } CSVWorld::ScriptErrorTable::ScriptErrorTable (const CSMDoc::Document& document, QWidget *parent) @@ -58,11 +70,14 @@ CSVWorld::ScriptErrorTable::ScriptErrorTable (const CSMDoc::Document& document, Compiler::registerExtensions (mExtensions); mContext.setExtensions (&mExtensions); + + setWarningsMode (CSMSettings::UserSettings::instance().settingValue ("script-editor/warnings")); } void CSVWorld::ScriptErrorTable::updateUserSetting (const QString& name, const QStringList& value) { - + if (name=="script-editor/warnings" && !value.isEmpty()) + setWarningsMode (value.at (0)); } void CSVWorld::ScriptErrorTable::update (const std::string& source) diff --git a/apps/opencs/view/world/scripterrortable.hpp b/apps/opencs/view/world/scripterrortable.hpp index 791125c127..99557fb0d6 100644 --- a/apps/opencs/view/world/scripterrortable.hpp +++ b/apps/opencs/view/world/scripterrortable.hpp @@ -32,6 +32,8 @@ namespace CSVWorld void addMessage (const std::string& message, CSMDoc::Message::Severity severity, int line = -1); + void setWarningsMode (const QString& value); + public: ScriptErrorTable (const CSMDoc::Document& document, QWidget *parent = 0); From 56ed0926bd9360365214450f61e3166f952f8ef3 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 17 Jul 2015 12:45:08 +0200 Subject: [PATCH 12/19] improved error table layout --- apps/opencs/view/world/scripterrortable.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/opencs/view/world/scripterrortable.cpp b/apps/opencs/view/world/scripterrortable.cpp index 29f1d6820a..dc28b8907a 100644 --- a/apps/opencs/view/world/scripterrortable.cpp +++ b/apps/opencs/view/world/scripterrortable.cpp @@ -66,7 +66,10 @@ CSVWorld::ScriptErrorTable::ScriptErrorTable (const CSMDoc::Document& document, QStringList headers; headers << "Severity" << "Line" << "Description"; setHorizontalHeaderLabels (headers); + horizontalHeader()->setResizeMode (0, QHeaderView::ResizeToContents); + horizontalHeader()->setResizeMode (1, QHeaderView::ResizeToContents); horizontalHeader()->setStretchLastSection (true); + verticalHeader()->hide(); Compiler::registerExtensions (mExtensions); mContext.setExtensions (&mExtensions); From 100af80388c197e191e71b6d6e533395b006d427 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 17 Jul 2015 13:06:51 +0200 Subject: [PATCH 13/19] made error table read only --- apps/opencs/view/world/scripterrortable.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/opencs/view/world/scripterrortable.cpp b/apps/opencs/view/world/scripterrortable.cpp index dc28b8907a..460bedefce 100644 --- a/apps/opencs/view/world/scripterrortable.cpp +++ b/apps/opencs/view/world/scripterrortable.cpp @@ -34,16 +34,22 @@ void CSVWorld::ScriptErrorTable::addMessage (const std::string& message, setRowCount (row+1); - setItem (row, 0, new QTableWidgetItem (QString::fromUtf8 (CSMDoc::Message::toString (severity).c_str()))); + QTableWidgetItem *severityItem = new QTableWidgetItem ( + QString::fromUtf8 (CSMDoc::Message::toString (severity).c_str())); + severityItem->setFlags (severityItem->flags() ^ Qt::ItemIsEditable); + setItem (row, 0, severityItem); if (line!=-1) { - QTableWidgetItem *item = new QTableWidgetItem; - item->setData (Qt::DisplayRole, line+1); - setItem (row, 1, item); + QTableWidgetItem *lineItem = new QTableWidgetItem; + lineItem->setData (Qt::DisplayRole, line+1); + lineItem->setFlags (lineItem->flags() ^ Qt::ItemIsEditable); + setItem (row, 1, lineItem); } - setItem (row, 2, new QTableWidgetItem (QString::fromUtf8 (message.c_str()))); + QTableWidgetItem *messageItem = new QTableWidgetItem (QString::fromUtf8 (message.c_str())); + messageItem->setFlags (messageItem->flags() ^ Qt::ItemIsEditable); + setItem (row, 2, messageItem); } From 0abd29a3b455e9fa0f55be0565ee8a1723473816 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 17 Jul 2015 13:42:25 +0200 Subject: [PATCH 14/19] jump to line in source text when clicking on an error in error table --- apps/opencs/view/world/scripterrortable.cpp | 10 ++++++++++ apps/opencs/view/world/scripterrortable.hpp | 8 ++++++++ apps/opencs/view/world/scriptsubview.cpp | 16 ++++++++++++++++ apps/opencs/view/world/scriptsubview.hpp | 2 ++ 4 files changed, 36 insertions(+) diff --git a/apps/opencs/view/world/scripterrortable.cpp b/apps/opencs/view/world/scripterrortable.cpp index 460bedefce..242d6c8ac9 100644 --- a/apps/opencs/view/world/scripterrortable.cpp +++ b/apps/opencs/view/world/scripterrortable.cpp @@ -77,10 +77,14 @@ CSVWorld::ScriptErrorTable::ScriptErrorTable (const CSMDoc::Document& document, horizontalHeader()->setStretchLastSection (true); verticalHeader()->hide(); + setSelectionMode (QAbstractItemView::NoSelection); + Compiler::registerExtensions (mExtensions); mContext.setExtensions (&mExtensions); setWarningsMode (CSMSettings::UserSettings::instance().settingValue ("script-editor/warnings")); + + connect (this, SIGNAL (cellClicked (int, int)), this, SLOT (cellClicked (int, int))); } void CSVWorld::ScriptErrorTable::updateUserSetting (const QString& name, const QStringList& value) @@ -112,3 +116,9 @@ void CSVWorld::ScriptErrorTable::update (const std::string& source) addMessage (error.what(), CSMDoc::Message::Severity_SeriousError); } } + +void CSVWorld::ScriptErrorTable::cellClicked (int row, int column) +{ + int line = item (row, 1)->data (Qt::DisplayRole).toInt(); + emit highlightError (line-1); +} diff --git a/apps/opencs/view/world/scripterrortable.hpp b/apps/opencs/view/world/scripterrortable.hpp index 99557fb0d6..5c6e751649 100644 --- a/apps/opencs/view/world/scripterrortable.hpp +++ b/apps/opencs/view/world/scripterrortable.hpp @@ -41,6 +41,14 @@ namespace CSVWorld void updateUserSetting (const QString& name, const QStringList& value); void update (const std::string& source); + + private slots: + + void cellClicked (int row, int column); + + signals: + + void highlightError (int line); }; } diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index d48e647d9b..36e21d53b9 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -98,6 +98,8 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: connect(mEditor, SIGNAL(cursorPositionChanged()), this, SLOT(updateStatusBar())); mErrors->update (source.toUtf8().constData()); + + connect (mErrors, SIGNAL (highlightError (int)), this, SLOT (highlightError (int))); } void CSVWorld::ScriptSubView::updateUserSetting (const QString& name, const QStringList& value) @@ -244,3 +246,17 @@ void CSVWorld::ScriptSubView::switchToId (const std::string& id) { switchToRow (mModel->getModelIndex (id, 0).row()); } + +void CSVWorld::ScriptSubView::highlightError (int line) +{ + QTextCursor cursor = mEditor->textCursor(); + + cursor.movePosition (QTextCursor::Start); + if (cursor.movePosition (QTextCursor::Down, QTextCursor::MoveAnchor, line)) + { +// cursor.movePosition (QTextCursor::Right, QTextCursor::MoveAnchor, column); + } + + mEditor->setFocus(); + mEditor->setTextCursor (cursor); +} diff --git a/apps/opencs/view/world/scriptsubview.hpp b/apps/opencs/view/world/scriptsubview.hpp index 0b6f4d9239..6be943bb80 100644 --- a/apps/opencs/view/world/scriptsubview.hpp +++ b/apps/opencs/view/world/scriptsubview.hpp @@ -75,6 +75,8 @@ namespace CSVWorld void switchToRow (int row); void switchToId (const std::string& id); + + void highlightError (int line); }; } From f665919046bf1b923424ad0af7944f60f8a5d47b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 17 Jul 2015 13:53:22 +0200 Subject: [PATCH 15/19] consider column when jumping to error in source text --- apps/opencs/view/world/scripterrortable.cpp | 20 +++++++++++++------- apps/opencs/view/world/scripterrortable.hpp | 4 ++-- apps/opencs/view/world/scriptsubview.cpp | 9 ++++----- apps/opencs/view/world/scriptsubview.hpp | 2 +- 4 files changed, 20 insertions(+), 15 deletions(-) diff --git a/apps/opencs/view/world/scripterrortable.cpp b/apps/opencs/view/world/scripterrortable.cpp index 242d6c8ac9..ec84a83284 100644 --- a/apps/opencs/view/world/scripterrortable.cpp +++ b/apps/opencs/view/world/scripterrortable.cpp @@ -18,7 +18,8 @@ void CSVWorld::ScriptErrorTable::report (const std::string& message, const Compi stream << message << " (" << loc.mLiteral << ")"; addMessage (stream.str(), type==Compiler::ErrorHandler::WarningMessage ? - CSMDoc::Message::Severity_Warning : CSMDoc::Message::Severity_Error, loc.mLine); + CSMDoc::Message::Severity_Warning : CSMDoc::Message::Severity_Error, + loc.mLine, loc.mColumn-loc.mLiteral.length()); } void CSVWorld::ScriptErrorTable::report (const std::string& message, Type type) @@ -28,7 +29,7 @@ void CSVWorld::ScriptErrorTable::report (const std::string& message, Type type) } void CSVWorld::ScriptErrorTable::addMessage (const std::string& message, - CSMDoc::Message::Severity severity, int line) + CSMDoc::Message::Severity severity, int line, int column) { int row = rowCount(); @@ -45,13 +46,16 @@ void CSVWorld::ScriptErrorTable::addMessage (const std::string& message, lineItem->setData (Qt::DisplayRole, line+1); lineItem->setFlags (lineItem->flags() ^ Qt::ItemIsEditable); setItem (row, 1, lineItem); + + QTableWidgetItem *columnItem = new QTableWidgetItem; + columnItem->setData (Qt::DisplayRole, column); + columnItem->setFlags (columnItem->flags() ^ Qt::ItemIsEditable); + setItem (row, 3, columnItem); } QTableWidgetItem *messageItem = new QTableWidgetItem (QString::fromUtf8 (message.c_str())); messageItem->setFlags (messageItem->flags() ^ Qt::ItemIsEditable); setItem (row, 2, messageItem); - - } void CSVWorld::ScriptErrorTable::setWarningsMode (const QString& value) @@ -67,7 +71,7 @@ void CSVWorld::ScriptErrorTable::setWarningsMode (const QString& value) CSVWorld::ScriptErrorTable::ScriptErrorTable (const CSMDoc::Document& document, QWidget *parent) : QTableWidget (parent), mContext (document.getData()) { - setColumnCount (3); + setColumnCount (4); QStringList headers; headers << "Severity" << "Line" << "Description"; @@ -76,6 +80,7 @@ CSVWorld::ScriptErrorTable::ScriptErrorTable (const CSMDoc::Document& document, horizontalHeader()->setResizeMode (1, QHeaderView::ResizeToContents); horizontalHeader()->setStretchLastSection (true); verticalHeader()->hide(); + setColumnHidden (3, true); setSelectionMode (QAbstractItemView::NoSelection); @@ -119,6 +124,7 @@ void CSVWorld::ScriptErrorTable::update (const std::string& source) void CSVWorld::ScriptErrorTable::cellClicked (int row, int column) { - int line = item (row, 1)->data (Qt::DisplayRole).toInt(); - emit highlightError (line-1); + int scriptLine = item (row, 1)->data (Qt::DisplayRole).toInt(); + int scriptColumn = item (row, 3)->data (Qt::DisplayRole).toInt(); + emit highlightError (scriptLine-1, scriptColumn); } diff --git a/apps/opencs/view/world/scripterrortable.hpp b/apps/opencs/view/world/scripterrortable.hpp index 5c6e751649..f16a96a74c 100644 --- a/apps/opencs/view/world/scripterrortable.hpp +++ b/apps/opencs/view/world/scripterrortable.hpp @@ -30,7 +30,7 @@ namespace CSVWorld ///< Report a file related error void addMessage (const std::string& message, CSMDoc::Message::Severity severity, - int line = -1); + int line = -1, int column = -1); void setWarningsMode (const QString& value); @@ -48,7 +48,7 @@ namespace CSVWorld signals: - void highlightError (int line); + void highlightError (int line, int column); }; } diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index 36e21d53b9..7b5b1131e3 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -99,7 +99,8 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: mErrors->update (source.toUtf8().constData()); - connect (mErrors, SIGNAL (highlightError (int)), this, SLOT (highlightError (int))); + connect (mErrors, SIGNAL (highlightError (int, int)), + this, SLOT (highlightError (int, int))); } void CSVWorld::ScriptSubView::updateUserSetting (const QString& name, const QStringList& value) @@ -247,15 +248,13 @@ void CSVWorld::ScriptSubView::switchToId (const std::string& id) switchToRow (mModel->getModelIndex (id, 0).row()); } -void CSVWorld::ScriptSubView::highlightError (int line) +void CSVWorld::ScriptSubView::highlightError (int line, int column) { QTextCursor cursor = mEditor->textCursor(); cursor.movePosition (QTextCursor::Start); if (cursor.movePosition (QTextCursor::Down, QTextCursor::MoveAnchor, line)) - { -// cursor.movePosition (QTextCursor::Right, QTextCursor::MoveAnchor, column); - } + cursor.movePosition (QTextCursor::Right, QTextCursor::MoveAnchor, column); mEditor->setFocus(); mEditor->setTextCursor (cursor); diff --git a/apps/opencs/view/world/scriptsubview.hpp b/apps/opencs/view/world/scriptsubview.hpp index 6be943bb80..a9c8dccb38 100644 --- a/apps/opencs/view/world/scriptsubview.hpp +++ b/apps/opencs/view/world/scriptsubview.hpp @@ -76,7 +76,7 @@ namespace CSVWorld void switchToId (const std::string& id); - void highlightError (int line); + void highlightError (int line, int column); }; } From 5febb96012ea68dda6cb367a18e1fe59a41cb39d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 17 Jul 2015 13:59:50 +0200 Subject: [PATCH 16/19] do not try to jump to source location for errors that do not have a source location --- apps/opencs/view/world/scripterrortable.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/world/scripterrortable.cpp b/apps/opencs/view/world/scripterrortable.cpp index ec84a83284..20b197c54e 100644 --- a/apps/opencs/view/world/scripterrortable.cpp +++ b/apps/opencs/view/world/scripterrortable.cpp @@ -124,7 +124,10 @@ void CSVWorld::ScriptErrorTable::update (const std::string& source) void CSVWorld::ScriptErrorTable::cellClicked (int row, int column) { - int scriptLine = item (row, 1)->data (Qt::DisplayRole).toInt(); - int scriptColumn = item (row, 3)->data (Qt::DisplayRole).toInt(); - emit highlightError (scriptLine-1, scriptColumn); + if (item (row, 1)) + { + int scriptLine = item (row, 1)->data (Qt::DisplayRole).toInt(); + int scriptColumn = item (row, 3)->data (Qt::DisplayRole).toInt(); + emit highlightError (scriptLine-1, scriptColumn); + } } From 73b6df8280dee4ad747c5f296401f63eab9f1efd Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 18 Jul 2015 13:09:17 +0200 Subject: [PATCH 17/19] put script compilation in script subview behind a timer --- apps/opencs/view/world/scriptsubview.cpp | 29 ++++++++++++++++++++++-- apps/opencs/view/world/scriptsubview.hpp | 6 +++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index 7b5b1131e3..dfdca8b48a 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include "../../model/doc/document.hpp" #include "../../model/world/universalid.hpp" @@ -35,6 +36,12 @@ void CSVWorld::ScriptSubView::addButtonBar() mButtons, SLOT (universalIdChanged (const CSMWorld::UniversalId&))); } +void CSVWorld::ScriptSubView::recompile() +{ + if (!mCompileDelay->isActive()) + mCompileDelay->start (5000); +} + CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) : SubView (id), mDocument (document), mColumn (-1), mBottom(0), mButtons (0), mCommandDispatcher (document, CSMWorld::UniversalId::getParentType (id.getType())) @@ -101,6 +108,12 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: connect (mErrors, SIGNAL (highlightError (int, int)), this, SLOT (highlightError (int, int))); + + mCompileDelay = new QTimer (this); + mCompileDelay->setSingleShot (true); + connect (mCompileDelay, SIGNAL (timeout()), this, SLOT (updateRequest())); + + recompile(); } void CSVWorld::ScriptSubView::updateUserSetting (const QString& name, const QStringList& value) @@ -136,6 +149,9 @@ void CSVWorld::ScriptSubView::updateUserSetting (const QString& name, const QStr mButtons->updateUserSetting (name, value); mErrors->updateUserSetting (name, value); + + if (name=="script-editor/warnings") + recompile(); } void CSVWorld::ScriptSubView::setStatusBar (bool show) @@ -198,7 +214,7 @@ void CSVWorld::ScriptSubView::textChanged() mDocument.getUndoStack().push (new CSMWorld::ModifyCommand (*mModel, mModel->getModelIndex (getUniversalId().getId(), mColumn), source)); - mErrors->update (source.toUtf8().constData()); + recompile(); } void CSVWorld::ScriptSubView::dataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) @@ -219,7 +235,7 @@ void CSVWorld::ScriptSubView::dataChanged (const QModelIndex& topLeft, const QMo mEditor->setPlainText (source); mEditor->setTextCursor (cursor); - mErrors->update (source.toUtf8().constData()); + recompile(); } } @@ -259,3 +275,12 @@ void CSVWorld::ScriptSubView::highlightError (int line, int column) mEditor->setFocus(); mEditor->setTextCursor (cursor); } + +void CSVWorld::ScriptSubView::updateRequest() +{ + QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn); + + QString source = mModel->data (index).toString(); + + mErrors->update (source.toUtf8().constData()); +} diff --git a/apps/opencs/view/world/scriptsubview.hpp b/apps/opencs/view/world/scriptsubview.hpp index a9c8dccb38..3481989f18 100644 --- a/apps/opencs/view/world/scriptsubview.hpp +++ b/apps/opencs/view/world/scriptsubview.hpp @@ -11,6 +11,7 @@ class QModelIndex; class QLabel; class QVBoxLayout; class QSplitter; +class QTime; namespace CSMDoc { @@ -43,11 +44,14 @@ namespace CSVWorld QVBoxLayout mLayout; QSplitter *mMain; ScriptErrorTable *mErrors; + QTimer *mCompileDelay; private: void addButtonBar(); + void recompile(); + public: ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); @@ -77,6 +81,8 @@ namespace CSVWorld void switchToId (const std::string& id); void highlightError (int line, int column); + + void updateRequest(); }; } From 8763a3b3c3e9250bd3399102b0f27fce102d7610 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 18 Jul 2015 15:32:38 +0200 Subject: [PATCH 18/19] make compilation delay configurable via a user setting --- apps/opencs/model/settings/usersettings.cpp | 6 ++++++ apps/opencs/view/world/scriptsubview.cpp | 7 ++++++- 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/settings/usersettings.cpp b/apps/opencs/model/settings/usersettings.cpp index 673db4057a..5a4b582663 100644 --- a/apps/opencs/model/settings/usersettings.cpp +++ b/apps/opencs/model/settings/usersettings.cpp @@ -319,6 +319,12 @@ void CSMSettings::UserSettings::buildSettingModelDefaults() Setting *toolbar = createSetting (Type_CheckBox, "toolbar", "Show toolbar"); toolbar->setDefaultValue ("true"); + Setting *delay = createSetting (Type_SpinBox, "compile-delay", + "Delay between updating of source errors"); + delay->setDefaultValue (100); + delay->setRange (0, 10000); + delay->setToolTip ("Delay in milliseconds"); + Setting *formatInt = createSetting (Type_LineEdit, "colour-int", "Highlight Colour: Int"); formatInt->setDefaultValues (QStringList() << "Dark magenta"); formatInt->setToolTip ("(Default: Green) Use one of the following formats:" + tooltip); diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index dfdca8b48a..ee0adb6f5f 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -39,7 +39,8 @@ void CSVWorld::ScriptSubView::addButtonBar() void CSVWorld::ScriptSubView::recompile() { if (!mCompileDelay->isActive()) - mCompileDelay->start (5000); + mCompileDelay->start ( + CSMSettings::UserSettings::instance().setting ("script-editor/compile-delay").toInt()); } CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) @@ -144,6 +145,10 @@ void CSVWorld::ScriptSubView::updateUserSetting (const QString& name, const QStr } } } + else if (name=="script-editor/compile-delay") + { + mCompileDelay->setInterval (value.at (0).toInt()); + } if (mButtons) mButtons->updateUserSetting (name, value); From f1ac440b7832dce0745c2e35bfa8c40ca4c66c36 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 18 Jul 2015 17:00:00 +0200 Subject: [PATCH 19/19] do not allow editing of deleted scripts --- apps/opencs/view/world/scripterrortable.cpp | 7 ++- apps/opencs/view/world/scripterrortable.hpp | 2 + apps/opencs/view/world/scriptsubview.cpp | 57 ++++++++++++++------- apps/opencs/view/world/scriptsubview.hpp | 5 ++ 4 files changed, 51 insertions(+), 20 deletions(-) diff --git a/apps/opencs/view/world/scripterrortable.cpp b/apps/opencs/view/world/scripterrortable.cpp index 20b197c54e..3e80c5bd47 100644 --- a/apps/opencs/view/world/scripterrortable.cpp +++ b/apps/opencs/view/world/scripterrortable.cpp @@ -100,7 +100,7 @@ void CSVWorld::ScriptErrorTable::updateUserSetting (const QString& name, const Q void CSVWorld::ScriptErrorTable::update (const std::string& source) { - setRowCount (0); + clear(); try { @@ -122,6 +122,11 @@ void CSVWorld::ScriptErrorTable::update (const std::string& source) } } +void CSVWorld::ScriptErrorTable::clear() +{ + setRowCount (0); +} + void CSVWorld::ScriptErrorTable::cellClicked (int row, int column) { if (item (row, 1)) diff --git a/apps/opencs/view/world/scripterrortable.hpp b/apps/opencs/view/world/scripterrortable.hpp index f16a96a74c..98db425cfd 100644 --- a/apps/opencs/view/world/scripterrortable.hpp +++ b/apps/opencs/view/world/scripterrortable.hpp @@ -42,6 +42,8 @@ namespace CSVWorld void update (const std::string& source); + void clear(); + private slots: void cellClicked (int row, int column); diff --git a/apps/opencs/view/world/scriptsubview.cpp b/apps/opencs/view/world/scriptsubview.cpp index ee0adb6f5f..d405d17652 100644 --- a/apps/opencs/view/world/scriptsubview.cpp +++ b/apps/opencs/view/world/scriptsubview.cpp @@ -38,11 +38,31 @@ void CSVWorld::ScriptSubView::addButtonBar() void CSVWorld::ScriptSubView::recompile() { - if (!mCompileDelay->isActive()) + if (!mCompileDelay->isActive() && !isDeleted()) mCompileDelay->start ( CSMSettings::UserSettings::instance().setting ("script-editor/compile-delay").toInt()); } +bool CSVWorld::ScriptSubView::isDeleted() const +{ + return mModel->data (mModel->getModelIndex (getUniversalId().getId(), mStateColumn)).toInt() + ==CSMWorld::RecordBase::State_Deleted; +} + +void CSVWorld::ScriptSubView::updateDeletedState() +{ + if (isDeleted()) + { + mErrors->clear(); + mEditor->setEnabled (false); + } + else + { + mEditor->setEnabled (true); + recompile(); + } +} + CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) : SubView (id), mDocument (document), mColumn (-1), mBottom(0), mButtons (0), mCommandDispatcher (document, CSMWorld::UniversalId::getParentType (id.getType())) @@ -68,16 +88,8 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: mModel = &dynamic_cast ( *document.getData().getTableModel (CSMWorld::UniversalId::Type_Scripts)); - for (int i=0; icolumnCount(); ++i) - if (mModel->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display)== - CSMWorld::ColumnBase::Display_ScriptFile) - { - mColumn = i; - break; - } - - if (mColumn==-1) - throw std::logic_error ("Can't find script column"); + mColumn = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_ScriptText); + mStateColumn = mModel->findColumnIndex (CSMWorld::Columns::ColumnId_Modification); QString source = mModel->data (mModel->getModelIndex (id.getId(), mColumn)).toString(); @@ -114,7 +126,7 @@ CSVWorld::ScriptSubView::ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc: mCompileDelay->setSingleShot (true); connect (mCompileDelay, SIGNAL (timeout()), this, SLOT (updateRequest())); - recompile(); + updateDeletedState(); } void CSVWorld::ScriptSubView::updateUserSetting (const QString& name, const QStringList& value) @@ -231,16 +243,21 @@ void CSVWorld::ScriptSubView::dataChanged (const QModelIndex& topLeft, const QMo QModelIndex index = mModel->getModelIndex (getUniversalId().getId(), mColumn); - if (index.row()>=topLeft.row() && index.row()<=bottomRight.row() && - index.column()>=topLeft.column() && index.column()<=bottomRight.column()) + if (index.row()>=topLeft.row() && index.row()<=bottomRight.row()) { - QString source = mModel->data (index).toString(); + if (mStateColumn>=topLeft.column() && mStateColumn<=bottomRight.column()) + updateDeletedState(); - QTextCursor cursor = mEditor->textCursor(); - mEditor->setPlainText (source); - mEditor->setTextCursor (cursor); + if (mColumn>=topLeft.column() && mColumn<=bottomRight.column()) + { + QString source = mModel->data (index).toString(); - recompile(); + QTextCursor cursor = mEditor->textCursor(); + mEditor->setPlainText (source); + mEditor->setTextCursor (cursor); + + recompile(); + } } } @@ -262,6 +279,8 @@ void CSVWorld::ScriptSubView::switchToRow (int row) std::vector selection (1, id); mCommandDispatcher.setSelection (selection); + + updateDeletedState(); } void CSVWorld::ScriptSubView::switchToId (const std::string& id) diff --git a/apps/opencs/view/world/scriptsubview.hpp b/apps/opencs/view/world/scriptsubview.hpp index 3481989f18..6125dd259d 100644 --- a/apps/opencs/view/world/scriptsubview.hpp +++ b/apps/opencs/view/world/scriptsubview.hpp @@ -38,6 +38,7 @@ namespace CSVWorld CSMDoc::Document& mDocument; CSMWorld::IdTable *mModel; int mColumn; + int mStateColumn; TableBottomBox *mBottom; RecordButtonBar *mButtons; CSMWorld::CommandDispatcher mCommandDispatcher; @@ -52,6 +53,10 @@ namespace CSVWorld void recompile(); + bool isDeleted() const; + + void updateDeletedState(); + public: ScriptSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document);