From b0ae78e889f2b55f99988304224b14519e8fd80a Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 6 Mar 2014 20:10:13 +0100 Subject: [PATCH 001/127] basicly enabled code --- apps/opencs/view/world/dialoguesubview.cpp | 3 +++ apps/opencs/view/world/dialoguesubview.hpp | 2 +- apps/opencs/view/world/subviews.cpp | 2 ++ 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index cedb20de92..a3d723de3f 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -12,6 +12,9 @@ #include "../../model/world/columnbase.hpp" #include "../../model/world/idtable.hpp" +#include "recordstatusdelegate.hpp" +#include "util.hpp" + CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete) : SubView (id) diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 64715f5b74..496730db58 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -18,7 +18,7 @@ namespace CSVWorld public: - DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete); + DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete = false); virtual void setEditLock (bool locked); }; diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 74ce03cce6..93ef7d2103 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -78,4 +78,6 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CreatorFactory >); manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory); + + manager.add(CSMWorld::UniversalId::Type_Region, new CSVDoc::SubViewFactory); } \ No newline at end of file From f0a45fa15feb05d5331924aef6e5a6fdf881653b Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 7 Mar 2014 17:15:43 +0100 Subject: [PATCH 002/127] just saved progress --- apps/opencs/CMakeLists.txt | 5 +- apps/opencs/view/world/dialoguesubview.cpp | 135 +++++++++++++++------ apps/opencs/view/world/dialoguesubview.hpp | 50 ++++++++ 3 files changed, 147 insertions(+), 43 deletions(-) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 6bcad1d08f..a7b39feb8c 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -60,7 +60,7 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool - scenetoolmode infocreator scriptedit + scenetoolmode infocreator scriptedit dialoguecreator ) opencs_units (view/render @@ -68,8 +68,7 @@ opencs_units (view/render ) opencs_units_noqt (view/world - dialoguesubview subviews - enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate + subviews enumdelegate vartypedelegate recordstatusdelegate idtypedelegate datadisplaydelegate scripthighlighter idvalidator dialoguecreator ) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index a3d723de3f..a411ca7f47 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -1,12 +1,17 @@ #include "dialoguesubview.hpp" +#include +#include + #include #include +#include #include #include #include #include +#include #include #include "../../model/world/columnbase.hpp" @@ -15,9 +20,88 @@ #include "recordstatusdelegate.hpp" #include "util.hpp" +CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, QUndoStack& undoStack) : +mParent(parent), +mTable(table), +mUndoStack(undoStack) +{} + +CSVWorld::CommandDelegate* CSVWorld::DialogueDelegateDispatcher::makeDelegate(CSMWorld::ColumnBase::Display display) +{ + CommandDelegate *delegate = NULL; + std::map::const_iterator delegateIt(mDelegates.find(display)); + if (delegateIt == mDelegates.end()) + { + delegate = CommandDelegateFactoryCollection::get().makeDelegate ( + display, mUndoStack, mParent); + mDelegates.insert(std::make_pair(display, delegate)); + } else + { + delegate = delegateIt->second; + } + connect(this, SIGNAL(closeEditor(QWidget *)), this, SLOT(editorDataCommited(QWidget*))); + return delegate; +} + +void CSVWorld::DialogueDelegateDispatcher::editorDataCommited( QWidget * editor ) +{ + std::cout<<"triggered"< + (mTable->headerData (index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); + + std::map::const_iterator delegateIt(mDelegates.find(display)); + if (delegateIt != mDelegates.end()) + { + delegateIt->second->setEditorData(editor, index); + } +} + +void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const +{ + CSMWorld::ColumnBase::Display display = static_cast + (mTable->headerData (index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); + + std::cout<<"setting data\n"; + std::map::const_iterator delegateIt(mDelegates.find(display)); + if (delegateIt != mDelegates.end()) + { + delegateIt->second->setModelData(editor, model, index); + } else { + std::cout<<"oooops\n"; + } +} + +void CSVWorld::DialogueDelegateDispatcher::paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + //Does nothing +} + +QSize CSVWorld::DialogueDelegateDispatcher::sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + return QSize(); //silencing warning, otherwise does nothing +} + +QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index) +{ + QWidget* editor = NULL; + std::map::iterator delegateIt(mDelegates.find(display)); + if (delegateIt != mDelegates.end()) + { + editor = delegateIt->second->createEditor(dynamic_cast(mParent), QStyleOptionViewItem(), index); + } + return editor; +} + CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, - bool createAndDelete) -: SubView (id) + bool createAndDelete) : + + SubView (id), + mDispatcher(new DialogueDelegateDispatcher(this, dynamic_cast(document.getData().getTableModel (id)), document.getUndoStack())) + { QWidget *widget = new QWidget (this); @@ -33,6 +117,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mWidgetMapper = new QDataWidgetMapper (this); mWidgetMapper->setModel (model); + mWidgetMapper->setItemDelegate(mDispatcher.get()); for (int i=0; i (model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); - QWidget *widget = 0; + mDispatcher->makeDelegate(display); + QWidget *widget = mDispatcher->makeEditor(display, (model->index (0, i))); + + if (widget) + { + layout->addWidget (widget, i, 1); + mWidgetMapper->addMapping (widget, i); + } if (model->flags (model->index (0, i)) & Qt::ItemIsEditable) { - switch (display) - { - case CSMWorld::ColumnBase::Display_String: - layout->addWidget (widget = new QLineEdit, i, 1); - break; - - case CSMWorld::ColumnBase::Display_Integer: - - /// \todo configure widget properly (range) - layout->addWidget (widget = new QSpinBox, i, 1); - break; - - case CSMWorld::ColumnBase::Display_Float: - - /// \todo configure widget properly (range, format?) - layout->addWidget (widget = new QDoubleSpinBox, i, 1); - break; - - default: break; // silence warnings for other times for now - } } - else - { - switch (display) - { - case CSMWorld::ColumnBase::Display_String: - case CSMWorld::ColumnBase::Display_Integer: - case CSMWorld::ColumnBase::Display_Float: - - layout->addWidget (widget = new QLabel, i, 1); - break; - - default: break; // silence warnings for other times for now - } - } - - if (widget) - mWidgetMapper->addMapping (widget, i); } } diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 496730db58..142d942eb5 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -1,9 +1,22 @@ #ifndef CSV_WORLD_DIALOGUESUBVIEW_H #define CSV_WORLD_DIALOGUESUBVIEW_H +#include +#include + +#include + #include "../doc/subview.hpp" +#include "../../model/world/columnbase.hpp" class QDataWidgetMapper; +class QSize; +class QEvent; + +namespace CSMWorld +{ + class IdTable; +} namespace CSMDoc { @@ -12,9 +25,46 @@ namespace CSMDoc namespace CSVWorld { + class CommandDelegate; + + class DialogueDelegateDispatcher : public QAbstractItemDelegate + { + Q_OBJECT + std::map mDelegates; + + QObject* mParent; + + const CSMWorld::IdTable* mTable; //nor sure if it is needed TODO + + QUndoStack& mUndoStack; + + public: + DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, QUndoStack& undoStack); + + CSVWorld::CommandDelegate* makeDelegate(CSMWorld::ColumnBase::Display display); + + QWidget* makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index); + ///< will return null if delegate is not present, parent of the widget is same as for dispatcher itself + + virtual void setEditorData (QWidget* editor, const QModelIndex& index) const; + + virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; + + virtual void paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; + ///< does nothing + + virtual QSize sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const; + ///< does nothing + + private slots: + void editorDataCommited( QWidget * editor ); + + }; + class DialogueSubView : public CSVDoc::SubView { QDataWidgetMapper *mWidgetMapper; + std::auto_ptr mDispatcher; public: From 2e6b45dafbed4ac1c1e4f80154e62e035fdae210 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 7 Mar 2014 22:17:40 +0100 Subject: [PATCH 003/127] edit view, savind works --- CMakeLists.txt | 4 +- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/world/dialoguesubview.cpp | 82 ++++++++++++++++++---- apps/opencs/view/world/dialoguesubview.hpp | 44 ++++++++++-- apps/opencs/view/world/subviews.cpp | 1 + 5 files changed, 110 insertions(+), 23 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 954e161a1d..0f76e36880 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,8 +38,8 @@ if(EXISTS ${PROJECT_SOURCE_DIR}/.git) set(GIT_VERSION "${GIT_VERSION_MAJOR}.${GIT_VERSION_MINOR}.${GIT_VERSION_RELEASE}") - if(NOT ${OPENMW_VERSION} STREQUAL ${GIT_VERSION}) - message(FATAL_ERROR "Silly Zini forgot to update the version again...") +# if(NOT ${OPENMW_VERSION} STREQUAL ${GIT_VERSION}) +# message(FATAL_ERROR "Silly Zini forgot to update the version again...") else(NOT ${OPENMW_VERSION} STREQUAL ${GIT_VERSION}) set(OPENMW_VERSION_MAJOR ${GIT_VERSION_MAJOR}) set(OPENMW_VERSION_MINOR ${GIT_VERSION_MINOR}) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 5034d97538..b635f746ef 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -60,7 +60,7 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool - scenetoolmode infocreator scriptedit dialoguecreator + scenetoolmode infocreator scriptedit dialoguesubview ) opencs_units (view/render diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index a411ca7f47..37a2ab130e 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -20,11 +20,45 @@ #include "recordstatusdelegate.hpp" #include "util.hpp" +/* +==============================DialogueDelegateDispatcherProxy========================================== +*/ +CSVWorld::refWrapper::refWrapper(const QModelIndex& index) : +mIndex(index) +{} + +CSVWorld::DialogueDelegateDispatcherProxy::DialogueDelegateDispatcherProxy(QWidget* editor, CSMWorld::ColumnBase::Display display) : +mEditor(editor), +mDisplay(display), +mIndexWrapper(NULL) +{ +} + +void CSVWorld::DialogueDelegateDispatcherProxy::editorDataCommited() +{ + emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay); +} + +void CSVWorld::DialogueDelegateDispatcherProxy::setIndex(const QModelIndex& index) +{ + mIndexWrapper.reset(new refWrapper(index)); +} + +QWidget* CSVWorld::DialogueDelegateDispatcherProxy::getEditor() const +{ + return mEditor; +} + +/* +==============================DialogueDelegateDispatcher========================================== +*/ + CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, QUndoStack& undoStack) : mParent(parent), mTable(table), mUndoStack(undoStack) -{} +{ +} CSVWorld::CommandDelegate* CSVWorld::DialogueDelegateDispatcher::makeDelegate(CSMWorld::ColumnBase::Display display) { @@ -39,13 +73,13 @@ CSVWorld::CommandDelegate* CSVWorld::DialogueDelegateDispatcher::makeDelegate(CS { delegate = delegateIt->second; } - connect(this, SIGNAL(closeEditor(QWidget *)), this, SLOT(editorDataCommited(QWidget*))); return delegate; } -void CSVWorld::DialogueDelegateDispatcher::editorDataCommited( QWidget * editor ) +void CSVWorld::DialogueDelegateDispatcher::editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display) { - std::cout<<"triggered"<second->setEditorData(editor, index); } + + for (unsigned i = 0; i < mProxys.size(); ++i) + { + if (mProxys[i]->getEditor() == editor) + { + mProxys[i]->setIndex(index); + } + } } -void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const +void CSVWorld::DialogueDelegateDispatcher::setModelData(QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const { - CSMWorld::ColumnBase::Display display = static_cast - (mTable->headerData (index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); - - std::cout<<"setting data\n"; std::map::const_iterator delegateIt(mDelegates.find(display)); if (delegateIt != mDelegates.end()) { delegateIt->second->setModelData(editor, model, index); - } else { - std::cout<<"oooops\n"; } } @@ -92,15 +128,31 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: if (delegateIt != mDelegates.end()) { editor = delegateIt->second->createEditor(dynamic_cast(mParent), QStyleOptionViewItem(), index); + DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display); + connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); + connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)), this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display))); + mProxys.push_back(proxy); //deleted in the destructor } return editor; } +CSVWorld::DialogueDelegateDispatcher::~DialogueDelegateDispatcher() +{ + for (unsigned i = 0; i < mProxys.size(); ++i) + { + delete mProxys[i]; //unique_ptr could be handy + } +} + +/* +==============================DialogueSubView========================================== +*/ + CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete) : SubView (id), - mDispatcher(new DialogueDelegateDispatcher(this, dynamic_cast(document.getData().getTableModel (id)), document.getUndoStack())) + mDispatcher(this, dynamic_cast(document.getData().getTableModel (id)), document.getUndoStack()) { QWidget *widget = new QWidget (this); @@ -117,7 +169,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mWidgetMapper = new QDataWidgetMapper (this); mWidgetMapper->setModel (model); - mWidgetMapper->setItemDelegate(mDispatcher.get()); + mWidgetMapper->setItemDelegate(&mDispatcher); for (int i=0; i (model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); - mDispatcher->makeDelegate(display); - QWidget *widget = mDispatcher->makeEditor(display, (model->index (0, i))); + mDispatcher.makeDelegate(display); + QWidget *widget = mDispatcher.makeEditor(display, (model->index (0, i))); if (widget) { diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 142d942eb5..11cc918b19 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -27,6 +27,36 @@ namespace CSVWorld { class CommandDelegate; + class refWrapper + { + public: + refWrapper(const QModelIndex& index); + + const QModelIndex& mIndex; + }; + + class DialogueDelegateDispatcherProxy : public QObject + { + Q_OBJECT + QWidget* mEditor; + + CSMWorld::ColumnBase::Display mDisplay; + + + + std::auto_ptr mIndexWrapper; + public: + DialogueDelegateDispatcherProxy(QWidget* editor, CSMWorld::ColumnBase::Display display); + QWidget* getEditor() const; + + public slots: + void editorDataCommited(); + void setIndex(const QModelIndex& index); + + signals: + void editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display); + }; + class DialogueDelegateDispatcher : public QAbstractItemDelegate { Q_OBJECT @@ -34,13 +64,17 @@ namespace CSVWorld QObject* mParent; - const CSMWorld::IdTable* mTable; //nor sure if it is needed TODO + CSMWorld::IdTable* mTable; //nor sure if it is needed TODO QUndoStack& mUndoStack; + std::vector mProxys; //once we move to the C++11 we should use unique_ptr + public: DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, QUndoStack& undoStack); + ~DialogueDelegateDispatcher(); + CSVWorld::CommandDelegate* makeDelegate(CSMWorld::ColumnBase::Display display); QWidget* makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index); @@ -48,7 +82,7 @@ namespace CSVWorld virtual void setEditorData (QWidget* editor, const QModelIndex& index) const; - virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index) const; + virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const; virtual void paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; ///< does nothing @@ -56,15 +90,15 @@ namespace CSVWorld virtual QSize sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const; ///< does nothing - private slots: - void editorDataCommited( QWidget * editor ); + private slots: + void editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display); }; class DialogueSubView : public CSVDoc::SubView { QDataWidgetMapper *mWidgetMapper; - std::auto_ptr mDispatcher; + DialogueDelegateDispatcher mDispatcher; public: diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 93ef7d2103..4a94cbfe67 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -80,4 +80,5 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory); manager.add(CSMWorld::UniversalId::Type_Region, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Spell, new CSVDoc::SubViewFactory); } \ No newline at end of file From 3c60345d6b08081b5246299e652cfec7f2e6f23f Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 8 Mar 2014 15:10:55 +0100 Subject: [PATCH 004/127] nest wrapper into the proxy class --- apps/opencs/view/world/dialoguesubview.cpp | 2 +- apps/opencs/view/world/dialoguesubview.hpp | 18 +++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 37a2ab130e..65a3f437dd 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -23,7 +23,7 @@ /* ==============================DialogueDelegateDispatcherProxy========================================== */ -CSVWorld::refWrapper::refWrapper(const QModelIndex& index) : +CSVWorld::DialogueDelegateDispatcherProxy::refWrapper::refWrapper(const QModelIndex& index) : mIndex(index) {} diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 11cc918b19..06c849e390 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -27,23 +27,23 @@ namespace CSVWorld { class CommandDelegate; - class refWrapper - { - public: - refWrapper(const QModelIndex& index); - - const QModelIndex& mIndex; - }; + //this can't be nested into the DialogueDelegateDispatcher, because it needs to emit signals class DialogueDelegateDispatcherProxy : public QObject { Q_OBJECT + class refWrapper + { + public: + refWrapper(const QModelIndex& index); + + const QModelIndex& mIndex; + }; + QWidget* mEditor; CSMWorld::ColumnBase::Display mDisplay; - - std::auto_ptr mIndexWrapper; public: DialogueDelegateDispatcherProxy(QWidget* editor, CSMWorld::ColumnBase::Display display); From a8b11829d4001c35d5d7c8345051d85e06eb3ea2 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 8 Mar 2014 15:18:40 +0100 Subject: [PATCH 005/127] disable not editable widgets --- apps/opencs/view/world/dialoguesubview.cpp | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 65a3f437dd..3eaa9bd610 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -189,11 +189,10 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM { layout->addWidget (widget, i, 1); mWidgetMapper->addMapping (widget, i); - } - - if (model->flags (model->index (0, i)) & Qt::ItemIsEditable) - { - + if (! (model->flags (model->index (0, i)) & Qt::ItemIsEditable)) + { + widget->setDisabled(true); + } } } } From 08ccae6b49ec22615b4cc6b7a047f4b2bbcd69d7 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 8 Mar 2014 15:27:43 +0100 Subject: [PATCH 006/127] handle comboboxes --- apps/opencs/model/world/columnbase.cpp | 5 +++++ apps/opencs/model/world/columnbase.hpp | 2 ++ apps/opencs/model/world/idtable.cpp | 5 +++++ apps/opencs/model/world/idtable.hpp | 2 ++ apps/opencs/view/world/dialoguesubview.cpp | 10 +++++++++- 5 files changed, 23 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/columnbase.cpp b/apps/opencs/model/world/columnbase.cpp index 34bad20cc5..f6363fe2eb 100644 --- a/apps/opencs/model/world/columnbase.cpp +++ b/apps/opencs/model/world/columnbase.cpp @@ -17,4 +17,9 @@ bool CSMWorld::ColumnBase::isUserEditable() const std::string CSMWorld::ColumnBase::getTitle() const { return Columns::getName (static_cast (mColumnId)); +} + +int CSMWorld::ColumnBase::getId() const +{ + return mColumnId; } \ No newline at end of file diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index e043336080..d990232f70 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -105,6 +105,8 @@ namespace CSMWorld ///< Can this column be edited directly by the user? virtual std::string getTitle() const; + + virtual int getId() const; }; template diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 453a7da6a3..97837e3687 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -230,4 +230,9 @@ std::pair CSMWorld::IdTable::view (int row) id = "sys::default"; return std::make_pair (UniversalId (UniversalId::Type_Scene, id), hint); +} + +int CSMWorld::IdTable::getColumnId(int column) const +{ + return mIdCollection->getColumn(column).getId(); } \ No newline at end of file diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index 5a271de443..0137413796 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -103,6 +103,8 @@ namespace CSMWorld std::pair view (int row) const; ///< Return the UniversalId and the hint for viewing \a row. If viewing is not /// supported by this table, return (UniversalId::Type_None, ""). + + int getColumnId(int column) const; }; } diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 3eaa9bd610..a946a6f6fb 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -16,6 +16,7 @@ #include "../../model/world/columnbase.hpp" #include "../../model/world/idtable.hpp" +#include "../../model/world/columns.hpp" #include "recordstatusdelegate.hpp" #include "util.hpp" @@ -123,13 +124,20 @@ QSize CSVWorld::DialogueDelegateDispatcher::sizeHint (const QStyleOptionViewItem QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index) { + bool hasEnums = CSMWorld::Columns::hasEnums(static_cast(mTable->getColumnId(index.column() ) ) ); QWidget* editor = NULL; std::map::iterator delegateIt(mDelegates.find(display)); if (delegateIt != mDelegates.end()) { editor = delegateIt->second->createEditor(dynamic_cast(mParent), QStyleOptionViewItem(), index); DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display); - connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); + if (hasEnums) //combox is used for all enums + { + connect(editor, SIGNAL(currentIndexChanged ( int)), proxy, SLOT(editorDataCommited())); + } else + { + connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); + } connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)), this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display))); mProxys.push_back(proxy); //deleted in the destructor } From 9612c6a6fd95d98c6ecc6ec5aea53df1ee593cab Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 8 Mar 2014 16:50:42 +0100 Subject: [PATCH 007/127] handle also bool boxes --- apps/opencs/view/world/dialoguesubview.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index a946a6f6fb..e8b53f2cdd 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -37,7 +37,10 @@ mIndexWrapper(NULL) void CSVWorld::DialogueDelegateDispatcherProxy::editorDataCommited() { - emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay); + if (mIndexWrapper.get()) + { + emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay); + } } void CSVWorld::DialogueDelegateDispatcherProxy::setIndex(const QModelIndex& index) @@ -79,7 +82,6 @@ CSVWorld::CommandDelegate* CSVWorld::DialogueDelegateDispatcher::makeDelegate(CS void CSVWorld::DialogueDelegateDispatcher::editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display) { - std::cout<<"triggered"<(mTable->getColumnId(index.column() ) ) ); + if (display == CSMWorld::ColumnBase::Display_Boolean) + { + hasEnums = true; + } + QWidget* editor = NULL; std::map::iterator delegateIt(mDelegates.find(display)); if (delegateIt != mDelegates.end()) @@ -133,7 +140,7 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display); if (hasEnums) //combox is used for all enums { - connect(editor, SIGNAL(currentIndexChanged ( int)), proxy, SLOT(editorDataCommited())); + connect(editor, SIGNAL(currentIndexChanged (int)), proxy, SLOT(editorDataCommited())); } else { connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); From 1f1774b5e12f17eade42d916608763252c809ea3 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 8 Mar 2014 16:54:05 +0100 Subject: [PATCH 008/127] changing the enumdelegate seteditordata --- apps/opencs/view/world/enumdelegate.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index fc9b7ee3b3..b882e20e69 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -60,7 +60,14 @@ void CSVWorld::EnumDelegate::setEditorData (QWidget *editor, const QModelIndex& { if (QComboBox *comboBox = dynamic_cast (editor)) { - int value = index.data (Qt::EditRole).toInt(); + QVariant data = index.data (Qt::EditRole); + + if (!data.isValid()) + { + data = index.data (Qt::DisplayRole); + } + + int value = data.toInt(); std::size_t size = mValues.size(); From 0447be7e7a2d6b2960d6ffaa1fca5cac47049b73 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sat, 8 Mar 2014 17:24:00 +0100 Subject: [PATCH 009/127] register extra views. do not display id --- apps/opencs/view/world/dialoguesubview.cpp | 7 +++++-- apps/opencs/view/world/subviews.cpp | 8 ++++++++ 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index e8b53f2cdd..76c66160af 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -192,7 +192,9 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM if (flags & CSMWorld::ColumnBase::Flag_Dialogue) { - layout->addWidget (new QLabel (model->headerData (i, Qt::Horizontal).toString()), i, 0); + if(i) //the first run adds the pointless id field + { + layout->addWidget (new QLabel (model->headerData (i, Qt::Horizontal).toString()), i-1, 0); CSMWorld::ColumnBase::Display display = static_cast (model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); @@ -202,13 +204,14 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM if (widget) { - layout->addWidget (widget, i, 1); + layout->addWidget (widget, i-1, 1); mWidgetMapper->addMapping (widget, i); if (! (model->flags (model->index (0, i)) & Qt::ItemIsEditable)) { widget->setDisabled(true); } } + } } } diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 4a94cbfe67..2109f08a09 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -81,4 +81,12 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) manager.add(CSMWorld::UniversalId::Type_Region, new CSVDoc::SubViewFactory); manager.add(CSMWorld::UniversalId::Type_Spell, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Referenceable, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Birthsign, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Global, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Gmst, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Race, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Class, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Topic, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Reference, new CSVDoc::SubViewFactory); } \ No newline at end of file From 7eb10756d4ec48240acf72d23b447794c2f63605 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 9 Mar 2014 08:58:24 +0100 Subject: [PATCH 010/127] some extra views enabled --- apps/opencs/view/world/dialoguesubview.cpp | 7 ++----- apps/opencs/view/world/subviews.cpp | 1 + 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 76c66160af..e8b53f2cdd 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -192,9 +192,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM if (flags & CSMWorld::ColumnBase::Flag_Dialogue) { - if(i) //the first run adds the pointless id field - { - layout->addWidget (new QLabel (model->headerData (i, Qt::Horizontal).toString()), i-1, 0); + layout->addWidget (new QLabel (model->headerData (i, Qt::Horizontal).toString()), i, 0); CSMWorld::ColumnBase::Display display = static_cast (model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); @@ -204,14 +202,13 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM if (widget) { - layout->addWidget (widget, i-1, 1); + layout->addWidget (widget, i, 1); mWidgetMapper->addMapping (widget, i); if (! (model->flags (model->index (0, i)) & Qt::ItemIsEditable)) { widget->setDisabled(true); } } - } } } diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 2109f08a09..2fa2fc06be 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -89,4 +89,5 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) manager.add(CSMWorld::UniversalId::Type_Class, new CSVDoc::SubViewFactory); manager.add(CSMWorld::UniversalId::Type_Topic, new CSVDoc::SubViewFactory); manager.add(CSMWorld::UniversalId::Type_Reference, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Cell, new CSVDoc::SubViewFactory); } \ No newline at end of file From 2de862126a42edad6e6ed0adbb61c34a3b4ae23f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 9 Mar 2014 11:42:39 +0100 Subject: [PATCH 011/127] moved resources group creation from Engine to bsa component --- apps/openmw/engine.cpp | 49 ++------------------------------- apps/openmw/engine.hpp | 3 -- components/CMakeLists.txt | 2 +- components/bsa/resources.cpp | 53 ++++++++++++++++++++++++++++++++++++ components/bsa/resources.hpp | 16 +++++++++++ 5 files changed, 72 insertions(+), 51 deletions(-) create mode 100644 components/bsa/resources.cpp create mode 100644 components/bsa/resources.hpp diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 4c3cadb3b6..37821b990f 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -12,7 +12,7 @@ #include -#include +#include #include #include #include @@ -192,50 +192,6 @@ OMW::Engine::~Engine() SDL_Quit(); } -// Load BSA files - -void OMW::Engine::loadBSA() -{ - // We use separate resource groups to handle location priority. - const Files::PathContainer& dataDirs = mFileCollections.getPaths(); - - int i=0; - for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter) - { - // Last data dir has the highest priority - std::string groupName = "Data" + Ogre::StringConverter::toString(dataDirs.size()-i, 8, '0'); - Ogre::ResourceGroupManager::getSingleton ().createResourceGroup (groupName); - - std::string dataDirectory = iter->string(); - std::cout << "Data dir " << dataDirectory << std::endl; - Bsa::addDir(dataDirectory, mFSStrict, groupName); - ++i; - } - - i=0; - for (std::vector::const_iterator archive = mArchives.begin(); archive != mArchives.end(); ++archive) - { - if (mFileCollections.doesExist(*archive)) - { - // Last BSA has the highest priority - std::string groupName = "DataBSA" + Ogre::StringConverter::toString(mArchives.size()-i, 8, '0'); - - Ogre::ResourceGroupManager::getSingleton ().createResourceGroup (groupName); - - const std::string archivePath = mFileCollections.getPath(*archive).string(); - std::cout << "Adding BSA archive " << archivePath << std::endl; - Bsa::addBSA(archivePath, groupName); - ++i; - } - else - { - std::stringstream message; - message << "Archive '" << *archive << "' not found"; - throw std::runtime_error(message.str()); - } - } -} - // add resources directory // \note This function works recursively. @@ -385,8 +341,7 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) mOgre->createWindow("OpenMW", windowSettings); - loadBSA(); - + Bsa::registerResources (mFileCollections, mArchives, true, mFSStrict); // Create input and UI first to set up a bootstrapping environment for // showing a loading screen and keeping the window responsive while doing so diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index 5c15ddf6fc..e0f51d0dcb 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -101,9 +101,6 @@ namespace OMW /// add a .zip resource void addZipResource (const boost::filesystem::path& path); - /// Load BSA files - void loadBSA(); - void executeLocalScripts(); virtual bool frameRenderingQueued (const Ogre::FrameEvent& evt); diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index db4ecad0b1..f8a2969f9d 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -15,7 +15,7 @@ add_component_dir (nifoverrides ) add_component_dir (bsa - bsa_archive bsa_file + bsa_archive bsa_file resources ) add_component_dir (nif diff --git a/components/bsa/resources.cpp b/components/bsa/resources.cpp new file mode 100644 index 0000000000..d06b3b4852 --- /dev/null +++ b/components/bsa/resources.cpp @@ -0,0 +1,53 @@ + +#include "resources.hpp" + +#include + +#include +#include + +#include "bsa_archive.hpp" + +void Bsa::registerResources (const Files::Collections& collections, + const std::vector& archives, bool useLooseFiles, bool fsStrict) +{ + const Files::PathContainer& dataDirs = collections.getPaths(); + + int i=0; + + if (useLooseFiles) + for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter) + { + // Last data dir has the highest priority + std::string groupName = "Data" + Ogre::StringConverter::toString(dataDirs.size()-i, 8, '0'); + Ogre::ResourceGroupManager::getSingleton ().createResourceGroup (groupName); + + std::string dataDirectory = iter->string(); + std::cout << "Data dir " << dataDirectory << std::endl; + Bsa::addDir(dataDirectory, fsStrict, groupName); + ++i; + } + + i=0; + for (std::vector::const_iterator archive = archives.begin(); archive != archives.end(); ++archive) + { + if (collections.doesExist(*archive)) + { + // Last BSA has the highest priority + std::string groupName = "DataBSA" + Ogre::StringConverter::toString(archives.size()-i, 8, '0'); + + Ogre::ResourceGroupManager::getSingleton ().createResourceGroup (groupName); + + const std::string archivePath = collections.getPath(*archive).string(); + std::cout << "Adding BSA archive " << archivePath << std::endl; + Bsa::addBSA(archivePath, groupName); + ++i; + } + else + { + std::stringstream message; + message << "Archive '" << *archive << "' not found"; + throw std::runtime_error(message.str()); + } + } +} \ No newline at end of file diff --git a/components/bsa/resources.hpp b/components/bsa/resources.hpp new file mode 100644 index 0000000000..8c3fb7bef8 --- /dev/null +++ b/components/bsa/resources.hpp @@ -0,0 +1,16 @@ +#ifndef BSA_BSA_RESOURCES_H +#define BSA_BSA_RESOURCES_H + +#include +#include + +#include "../files/collections.hpp" + +namespace Bsa +{ + void registerResources (const Files::Collections& collections, + const std::vector& archives, bool useLooseFiles, bool fsStrict); + ///< Register resources directories and archives as OGRE resources groups +} + +#endif From 2b17f5dde95044c01e07c494417c93f75e87c0cc Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 9 Mar 2014 12:32:21 +0100 Subject: [PATCH 012/127] register resources locations on editor startup --- apps/opencs/editor.cpp | 19 ++++++++++++++----- apps/opencs/editor.hpp | 4 ++-- 2 files changed, 16 insertions(+), 7 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 2b2f41754b..9eb95fafac 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -11,6 +11,8 @@ #include +#include + #include "model/doc/document.hpp" #include "model/world/data.hpp" @@ -18,14 +20,17 @@ CS::Editor::Editor (OgreInit::OgreInit& ogreInit) : mDocumentManager (mCfgMgr), mViewManager (mDocumentManager), mIpcServerName ("org.openmw.OpenCS") { - Files::PathContainer dataDirs = readConfig(); + std::pair > config = readConfig(); - setupDataFiles (dataDirs); + setupDataFiles (config.first); CSMSettings::UserSettings::instance().loadSettings ("opencs.cfg"); ogreInit.init ((mCfgMgr.getUserConfigPath() / "opencsOgre.log").string()); + Bsa::registerResources (Files::Collections (config.first, !mFsStrict), config.second, true, + mFsStrict); + mNewGame.setLocalData (mLocal); mFileDialog.setLocalData (mLocal); @@ -58,7 +63,7 @@ void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs) } } -Files::PathContainer CS::Editor::readConfig() +std::pair > CS::Editor::readConfig() { boost::program_options::variables_map variables; boost::program_options::options_description desc("Syntax: opencs \nAllowed options"); @@ -68,7 +73,9 @@ Files::PathContainer CS::Editor::readConfig() ("data-local", boost::program_options::value()->default_value("")) ("fs-strict", boost::program_options::value()->implicit_value(true)->default_value(false)) ("encoding", boost::program_options::value()->default_value("win1252")) - ("resources", boost::program_options::value()->default_value("resources")); + ("resources", boost::program_options::value()->default_value("resources")) + ("fallback-archive", boost::program_options::value >()-> + default_value(std::vector(), "fallback-archive")->multitoken()); boost::program_options::notify(variables); @@ -76,6 +83,8 @@ Files::PathContainer CS::Editor::readConfig() mDocumentManager.setResourceDir (variables["resources"].as()); + mFsStrict = variables["fs-strict"].as(); + Files::PathContainer dataDirs, dataLocal; if (!variables["data"].empty()) { dataDirs = Files::PathContainer(variables["data"].as()); @@ -105,7 +114,7 @@ Files::PathContainer CS::Editor::readConfig() dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end()); - return dataDirs; + return std::make_pair (dataDirs, variables["fallback-archive"].as >()); } void CS::Editor::createGame() diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 0f1c7a682d..ec417ba8e0 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -41,12 +41,12 @@ namespace CS CSVDoc::NewGameDialogue mNewGame; CSVSettings::UserSettingsDialog mSettings; CSVDoc::FileDialog mFileDialog; - boost::filesystem::path mLocal; + bool mFsStrict; void setupDataFiles (const Files::PathContainer& dataDirs); - Files::PathContainer readConfig(); + std::pair > readConfig(); ///< \return data paths // not implemented From b2fdaa74b0bdc9fb45de67fd45608249a09aafe2 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Sun, 9 Mar 2014 18:44:04 +0100 Subject: [PATCH 013/127] trying to set the size policy --- apps/opencs/view/world/dialoguesubview.cpp | 42 +++++++++++++++++----- 1 file changed, 33 insertions(+), 9 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index e8b53f2cdd..6307afabb2 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -174,9 +174,21 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM setWidget (widget); - QGridLayout *layout = new QGridLayout; + QFrame* line = new QFrame(this); + line->setObjectName(QString::fromUtf8("line")); + line->setGeometry(QRect(320, 150, 118, 3)); + line->setFrameShape(QFrame::HLine); + line->setFrameShadow(QFrame::Sunken); - widget->setLayout (layout); + QVBoxLayout *mainLayout = new QVBoxLayout; + QGridLayout *unlockedLayout = new QGridLayout; + QGridLayout *lockedLayout = new QGridLayout; + mainLayout->addLayout(lockedLayout, 0); + mainLayout->addWidget(line, 1); + mainLayout->addLayout(unlockedLayout, 2); + mainLayout->addStretch(1); + + widget->setLayout (mainLayout); QAbstractItemModel *model = document.getData().getTableModel (id); @@ -186,27 +198,39 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mWidgetMapper->setModel (model); mWidgetMapper->setItemDelegate(&mDispatcher); + int unlocked = 0; + int locked = 0; + std::vector editors; for (int i=0; iheaderData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt(); if (flags & CSMWorld::ColumnBase::Flag_Dialogue) { - layout->addWidget (new QLabel (model->headerData (i, Qt::Horizontal).toString()), i, 0); - CSMWorld::ColumnBase::Display display = static_cast (model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); mDispatcher.makeDelegate(display); - QWidget *widget = mDispatcher.makeEditor(display, (model->index (0, i))); + QWidget *editor = mDispatcher.makeEditor(display, (model->index (0, i))); - if (widget) + if (editor) { - layout->addWidget (widget, i, 1); - mWidgetMapper->addMapping (widget, i); + editors.push_back(editor); + mWidgetMapper->addMapping (editor, i); + QLabel* label = new QLabel(model->headerData (i, Qt::Horizontal).toString()); + label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); + editor->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); if (! (model->flags (model->index (0, i)) & Qt::ItemIsEditable)) { - widget->setDisabled(true); + editor->setDisabled(true); + lockedLayout->addWidget (label, locked, 0); + lockedLayout->addWidget (editor, locked, 1); + ++locked; + } else + { + unlockedLayout->addWidget (label, unlocked, 0); + unlockedLayout->addWidget (editor, unlocked, 1); + ++unlocked; } } } From 9ab920bd802e2d248f8977e9d8a7879579214fa5 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 10 Mar 2014 09:37:53 +0100 Subject: [PATCH 014/127] display id and other not editable data --- apps/opencs/view/world/enumdelegate.cpp | 4 ++++ apps/opencs/view/world/util.cpp | 32 ++++++++++++++++++++++++- apps/opencs/view/world/util.hpp | 3 +++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index b882e20e69..7f40b966dc 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -65,6 +65,10 @@ void CSVWorld::EnumDelegate::setEditorData (QWidget *editor, const QModelIndex& if (!data.isValid()) { data = index.data (Qt::DisplayRole); + if (!data.isValid()) + { + return; + } } int value = data.toInt(); diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index 97af3b99c5..fd35ef3ef9 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -4,6 +4,8 @@ #include #include +#include +#include #include "../../model/world/commands.hpp" @@ -119,7 +121,7 @@ void CSVWorld::CommandDelegate::setModelData (QWidget *editor, QAbstractItemMode QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const { - if (!index.data().isValid()) + if (!(index.data(Qt::EditRole).isValid() or index.data(Qt::DisplayRole).isValid())) return 0; return QStyledItemDelegate::createEditor (parent, option, index); @@ -140,4 +142,32 @@ bool CSVWorld::CommandDelegate::updateEditorSetting (const QString &settingName, const QString &settingValue) { return false; +} + +void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelIndex& index) const +{ + QVariant v = index.data(Qt::EditRole); + if (!v.isValid()) + { + v = index.data(Qt::DisplayRole); + if (!v.isValid()) + { + return; + } + } + + QByteArray n = editor->metaObject()->userProperty().name(); + + if (n == "dateTime") { + if (editor->inherits("QTimeEdit")) + n = "time"; + else if (editor->inherits("QDateEdit")) + n = "date"; + } + + if (!n.isEmpty()) { + if (!v.isValid()) + v = QVariant(editor->property(n).userType(), (const void *)0); + editor->setProperty(n, v); + } } \ No newline at end of file diff --git a/apps/opencs/view/world/util.hpp b/apps/opencs/view/world/util.hpp index 87f118cd74..0d04dda4ee 100644 --- a/apps/opencs/view/world/util.hpp +++ b/apps/opencs/view/world/util.hpp @@ -111,6 +111,9 @@ namespace CSVWorld virtual bool updateEditorSetting (const QString &settingName, const QString &settingValue); ///< \return Does column require update? + virtual void setEditorData (QWidget *editor, const QModelIndex& index) const; + + private slots: virtual void slotUpdateEditorSetting (const QString &settingName, const QString &settingValue) {} From 361bc559730f292985d57b0420045054700df44f Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 10 Mar 2014 09:47:41 +0100 Subject: [PATCH 015/127] dont force trying display --- apps/opencs/view/world/dialoguesubview.cpp | 2 +- apps/opencs/view/world/enumdelegate.cpp | 4 ++-- apps/opencs/view/world/enumdelegate.hpp | 2 +- apps/opencs/view/world/util.cpp | 12 +++++++----- apps/opencs/view/world/util.hpp | 2 +- 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 6307afabb2..6145c9dfa7 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -93,7 +93,7 @@ void CSVWorld::DialogueDelegateDispatcher::setEditorData (QWidget* editor, const std::map::const_iterator delegateIt(mDelegates.find(display)); if (delegateIt != mDelegates.end()) { - delegateIt->second->setEditorData(editor, index); + delegateIt->second->setEditorData(editor, index, true); } for (unsigned i = 0; i < mProxys.size(); ++i) diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index 7f40b966dc..a6089a1b36 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -56,13 +56,13 @@ QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptio return comboBox; } -void CSVWorld::EnumDelegate::setEditorData (QWidget *editor, const QModelIndex& index) const +void CSVWorld::EnumDelegate::setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay) const { if (QComboBox *comboBox = dynamic_cast (editor)) { QVariant data = index.data (Qt::EditRole); - if (!data.isValid()) + if (tryDisplay && !data.isValid()) { data = index.data (Qt::DisplayRole); if (!data.isValid()) diff --git a/apps/opencs/view/world/enumdelegate.hpp b/apps/opencs/view/world/enumdelegate.hpp index 606f9278a1..ac07f3d1ed 100644 --- a/apps/opencs/view/world/enumdelegate.hpp +++ b/apps/opencs/view/world/enumdelegate.hpp @@ -34,7 +34,7 @@ namespace CSVWorld virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index) const; - virtual void setEditorData (QWidget *editor, const QModelIndex& index) const; + virtual void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay = false) const; virtual void paint (QPainter *painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index fd35ef3ef9..74aaeb6f0e 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -144,18 +144,20 @@ bool CSVWorld::CommandDelegate::updateEditorSetting (const QString &settingName, return false; } -void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelIndex& index) const +void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay) const { QVariant v = index.data(Qt::EditRole); - if (!v.isValid()) + if (tryDisplay) { - v = index.data(Qt::DisplayRole); if (!v.isValid()) { - return; + v = index.data(Qt::DisplayRole); + if (!v.isValid()) + { + return; + } } } - QByteArray n = editor->metaObject()->userProperty().name(); if (n == "dateTime") { diff --git a/apps/opencs/view/world/util.hpp b/apps/opencs/view/world/util.hpp index 0d04dda4ee..23b9fcfac1 100644 --- a/apps/opencs/view/world/util.hpp +++ b/apps/opencs/view/world/util.hpp @@ -111,7 +111,7 @@ namespace CSVWorld virtual bool updateEditorSetting (const QString &settingName, const QString &settingValue); ///< \return Does column require update? - virtual void setEditorData (QWidget *editor, const QModelIndex& index) const; + virtual void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay = false) const; private slots: From 73cb3ac0ed3f469877f04bebf26861b8bce43dbe Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 10 Mar 2014 12:04:03 +0100 Subject: [PATCH 016/127] embelishing --- apps/opencs/view/world/dialoguesubview.cpp | 14 ++++++++--- apps/opencs/view/world/enumdelegate.cpp | 4 +-- apps/opencs/view/world/enumdelegate.hpp | 6 +++-- apps/opencs/view/world/util.cpp | 29 +++++++++++++++++++++- apps/opencs/view/world/util.hpp | 6 +++-- 5 files changed, 48 insertions(+), 11 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 6145c9dfa7..c4e9b805c7 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -136,14 +136,20 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: std::map::iterator delegateIt(mDelegates.find(display)); if (delegateIt != mDelegates.end()) { - editor = delegateIt->second->createEditor(dynamic_cast(mParent), QStyleOptionViewItem(), index); + editor = delegateIt->second->createEditor(dynamic_cast(mParent), QStyleOptionViewItem(), index, display); DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display); - if (hasEnums) //combox is used for all enums + if (display == CSMWorld::ColumnBase::Display_Boolean) { - connect(editor, SIGNAL(currentIndexChanged (int)), proxy, SLOT(editorDataCommited())); + connect(editor, SIGNAL(stateChanged(int)), proxy, SLOT(editorDataCommited())); } else { - connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); + if (hasEnums) //combox is used for all enums + { + connect(editor, SIGNAL(currentIndexChanged (int)), proxy, SLOT(editorDataCommited())); + } else + { + connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); + } } connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)), this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display))); mProxys.push_back(proxy); //deleted in the destructor diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index a6089a1b36..858458b37b 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -42,9 +42,9 @@ CSVWorld::EnumDelegate::EnumDelegate (const std::vector } QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option, - const QModelIndex& index) const + const QModelIndex& index, CSMWorld::ColumnBase::Display display) const { - if (!index.data().isValid()) + if (!index.data(Qt::EditRole).isValid() && !index.data(Qt::DisplayRole).isValid()) return 0; QComboBox *comboBox = new QComboBox (parent); diff --git a/apps/opencs/view/world/enumdelegate.hpp b/apps/opencs/view/world/enumdelegate.hpp index ac07f3d1ed..8bd96a6f20 100644 --- a/apps/opencs/view/world/enumdelegate.hpp +++ b/apps/opencs/view/world/enumdelegate.hpp @@ -31,8 +31,10 @@ namespace CSVWorld EnumDelegate (const std::vector >& values, QUndoStack& undoStack, QObject *parent); - virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem& option, - const QModelIndex& index) const; + virtual QWidget *createEditor(QWidget *parent, + const QStyleOptionViewItem& option, + const QModelIndex& index, + CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None) const; virtual void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay = false) const; diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index 74aaeb6f0e..7e8cddd1f4 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -6,6 +6,11 @@ #include #include #include +#include +#include +#include +#include +#include #include "../../model/world/commands.hpp" @@ -119,10 +124,32 @@ void CSVWorld::CommandDelegate::setModelData (QWidget *editor, QAbstractItemMode } QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem& option, - const QModelIndex& index) const + const QModelIndex& index, CSMWorld::ColumnBase::Display display) const { if (!(index.data(Qt::EditRole).isValid() or index.data(Qt::DisplayRole).isValid())) + { return 0; + } + + if (display != CSMWorld::ColumnBase::Display_None) + { + if (display == CSMWorld::ColumnBase::Display_Integer) + { + return new QSpinBox(parent); + } + if (display == CSMWorld::ColumnBase::Display_Integer) + { + return new QDoubleSpinBox(parent); + } + if (display == CSMWorld::ColumnBase::Display_String) + { + return new QLineEdit(parent); + } + if (display == CSMWorld::ColumnBase::Display_Boolean) + { + return new QCheckBox(parent); + } + } return QStyledItemDelegate::createEditor (parent, option, index); } diff --git a/apps/opencs/view/world/util.hpp b/apps/opencs/view/world/util.hpp index 23b9fcfac1..814f09d3a2 100644 --- a/apps/opencs/view/world/util.hpp +++ b/apps/opencs/view/world/util.hpp @@ -101,8 +101,10 @@ namespace CSVWorld virtual void setModelData (QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const; - virtual QWidget *createEditor (QWidget *parent, const QStyleOptionViewItem& option, - const QModelIndex& index) const; + virtual QWidget *createEditor (QWidget *parent, + const QStyleOptionViewItem& option, + const QModelIndex& index, + CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None) const; void setEditLock (bool locked); From 7812427836200bfcb01ebd48477d319822125381 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 10 Mar 2014 12:44:34 +0100 Subject: [PATCH 017/127] added Preview submenu item; fixed View issues regarding exterior cells --- apps/opencs/model/world/data.cpp | 6 +-- apps/opencs/model/world/idtable.cpp | 9 ++++- apps/opencs/model/world/idtable.hpp | 5 ++- apps/opencs/model/world/universalid.cpp | 2 + apps/opencs/model/world/universalid.hpp | 3 +- apps/opencs/view/world/scenesubview.cpp | 2 +- apps/opencs/view/world/table.cpp | 51 ++++++++++++++++++------- apps/opencs/view/world/table.hpp | 3 ++ 8 files changed, 60 insertions(+), 21 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index d68b79ff0a..d60dcae117 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -250,9 +250,9 @@ CSMWorld::Data::Data() : mRefs (mCells) addModel (new IdTable (&mTopicInfos, IdTable::Reordering_WithinTopic), UniversalId::Type_TopicInfos, UniversalId::Type_TopicInfo); addModel (new IdTable (&mJournalInfos, IdTable::Reordering_WithinTopic), UniversalId::Type_JournalInfos, UniversalId::Type_JournalInfo); addModel (new IdTable (&mCells, IdTable::Reordering_None, IdTable::Viewing_Id), UniversalId::Type_Cells, UniversalId::Type_Cell); - addModel (new IdTable (&mReferenceables), UniversalId::Type_Referenceables, - UniversalId::Type_Referenceable); - addModel (new IdTable (&mRefs, IdTable::Reordering_None, IdTable::Viewing_Cell), UniversalId::Type_References, UniversalId::Type_Reference, false); + addModel (new IdTable (&mReferenceables, IdTable::Reordering_None, IdTable::Viewing_None, true), + UniversalId::Type_Referenceables, UniversalId::Type_Referenceable); + addModel (new IdTable (&mRefs, IdTable::Reordering_None, IdTable::Viewing_Cell, true), UniversalId::Type_References, UniversalId::Type_Reference, false); addModel (new IdTable (&mFilters), UniversalId::Type_Filters, UniversalId::Type_Filter, false); } diff --git a/apps/opencs/model/world/idtable.cpp b/apps/opencs/model/world/idtable.cpp index 453a7da6a3..56b16f5a15 100644 --- a/apps/opencs/model/world/idtable.cpp +++ b/apps/opencs/model/world/idtable.cpp @@ -5,8 +5,8 @@ #include "columnbase.hpp" CSMWorld::IdTable::IdTable (CollectionBase *idCollection, Reordering reordering, - Viewing viewing) -: mIdCollection (idCollection), mReordering (reordering), mViewing (viewing) + Viewing viewing, bool preview) +: mIdCollection (idCollection), mReordering (reordering), mViewing (viewing), mPreview (preview) {} CSMWorld::IdTable::~IdTable() @@ -196,6 +196,11 @@ CSMWorld::IdTable::Viewing CSMWorld::IdTable::getViewing() const return mViewing; } +bool CSMWorld::IdTable::hasPreview() const +{ + return mPreview; +} + std::pair CSMWorld::IdTable::view (int row) const { std::string id; diff --git a/apps/opencs/model/world/idtable.hpp b/apps/opencs/model/world/idtable.hpp index 5a271de443..7d812b083f 100644 --- a/apps/opencs/model/world/idtable.hpp +++ b/apps/opencs/model/world/idtable.hpp @@ -39,6 +39,7 @@ namespace CSMWorld CollectionBase *mIdCollection; Reordering mReordering; Viewing mViewing; + bool mPreview; // not implemented IdTable (const IdTable&); @@ -47,7 +48,7 @@ namespace CSMWorld public: IdTable (CollectionBase *idCollection, Reordering reordering = Reordering_None, - Viewing viewing = Viewing_None); + Viewing viewing = Viewing_None, bool preview = false); ///< The ownership of \a idCollection is not transferred. virtual ~IdTable(); @@ -100,6 +101,8 @@ namespace CSMWorld Viewing getViewing() const; + bool hasPreview() const; + std::pair view (int row) const; ///< Return the UniversalId and the hint for viewing \a row. If viewing is not /// supported by this table, return (UniversalId::Type_None, ""). diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index 1d1b3c960f..a62acc02bb 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -92,6 +92,8 @@ namespace { CSMWorld::UniversalId::Class_SubRecord, CSMWorld::UniversalId::Type_Filter, "Filter", ":./filter.png" }, { CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Scene, "Scene", 0 }, + { CSMWorld::UniversalId::Class_Collection, CSMWorld::UniversalId::Type_Preview, "Preview", 0 }, + { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0, 0 } // end marker }; diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index 0c17da03be..34167cd854 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -95,7 +95,8 @@ namespace CSMWorld Type_TopicInfo, Type_JournalInfos, Type_JournalInfo, - Type_Scene + Type_Scene, + Type_Preview }; enum { NumberOfTypes = Type_Scene+1 }; diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 3601ae0942..66e0266046 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -34,7 +34,7 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D SceneToolbar *toolbar = new SceneToolbar (48, this); - if (id.getId()[0]=='#') + if (id.getId()=="sys::default") mScene = new CSVRender::PagedWorldspaceWidget (this); else mScene = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this); diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index 4bb9955e6e..29bca2f6b3 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -39,18 +39,6 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) if (mCreateAction) menu.addAction(mCloneAction); - - if (mModel->getViewing()!=CSMWorld::IdTable::Viewing_None) - { - int row = selectedRows.begin()->row(); - - row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row(); - - CSMWorld::UniversalId id = mModel->view (row).first; - - if (!mDocument.getData().getCells().getRecord (id.getId()).isDeleted()) - menu.addAction (mViewAction); - } } if (mCreateAction) @@ -95,6 +83,28 @@ void CSVWorld::Table::contextMenuEvent (QContextMenuEvent *event) } } + if (selectedRows.size()==1) + { + if (mModel->getViewing()!=CSMWorld::IdTable::Viewing_None) + { + int row = selectedRows.begin()->row(); + + row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row(); + + CSMWorld::UniversalId id = mModel->view (row).first; + + int index = mDocument.getData().getCells().searchId (id.getId()); + // index==-1: the ID references a worldspace instead of a cell (ignore for now and go + // ahead) + + if (index==-1 || !mDocument.getData().getCells().getRecord (index).isDeleted()) + menu.addAction (mViewAction); + } + + if (mModel->hasPreview()) + menu.addAction (mPreviewAction); + } + menu.exec (event->globalPos()); } @@ -249,6 +259,10 @@ CSVWorld::Table::Table (const CSMWorld::UniversalId& id, connect (mViewAction, SIGNAL (triggered()), this, SLOT (viewRecord())); addAction (mViewAction); + mPreviewAction = new QAction (tr ("Preview"), this); + connect (mPreviewAction, SIGNAL (triggered()), this, SLOT (previewRecord())); + addAction (mPreviewAction); + connect (mProxyModel, SIGNAL (rowsInserted (const QModelIndex&, int, int)), this, SLOT (tableSizeUpdate())); @@ -406,7 +420,7 @@ void CSVWorld::Table::viewRecord() if (selectedRows.size()==1) { - int row =selectedRows.begin()->row(); + int row = selectedRows.begin()->row(); row = mProxyModel->mapToSource (mProxyModel->index (row, 0)).row(); @@ -417,6 +431,17 @@ void CSVWorld::Table::viewRecord() } } +void CSVWorld::Table::previewRecord() +{ + QModelIndexList selectedRows = selectionModel()->selectedRows(); + + if (selectedRows.size()==1) + { + std::string id = getUniversalId (selectedRows.begin()->row()).getId(); + + emit editRequest (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Preview, id) , ""); + } +} void CSVWorld::Table::updateEditorSetting (const QString &settingName, const QString &settingValue) { int columns = mModel->columnCount(); diff --git a/apps/opencs/view/world/table.hpp b/apps/opencs/view/world/table.hpp index e8d5648d16..4231a4a432 100644 --- a/apps/opencs/view/world/table.hpp +++ b/apps/opencs/view/world/table.hpp @@ -44,6 +44,7 @@ namespace CSVWorld QAction *mMoveUpAction; QAction *mMoveDownAction; QAction *mViewAction; + QAction *mPreviewAction; CSMWorld::IdTableProxyModel *mProxyModel; CSMWorld::IdTable *mModel; bool mEditLock; @@ -111,6 +112,8 @@ namespace CSVWorld void viewRecord(); + void previewRecord(); + public slots: void tableSizeUpdate(); From 874847c959a7e4e93902b1dd891e06d823182f36 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 10 Mar 2014 13:25:01 +0100 Subject: [PATCH 018/127] handle color --- apps/opencs/view/world/dialoguesubview.cpp | 15 +++++++-------- apps/opencs/view/world/util.cpp | 16 +++++++++++++--- 2 files changed, 20 insertions(+), 11 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index c4e9b805c7..6a37ce59c9 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -127,9 +127,14 @@ QSize CSVWorld::DialogueDelegateDispatcher::sizeHint (const QStyleOptionViewItem QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index) { bool hasEnums = CSMWorld::Columns::hasEnums(static_cast(mTable->getColumnId(index.column() ) ) ); - if (display == CSMWorld::ColumnBase::Display_Boolean) + QVariant variant = index.data(); + if (!variant.isValid()) { - hasEnums = true; + variant = index.data(Qt::DisplayRole); + if (!variant.isValid()) + { + return 0; + } } QWidget* editor = NULL; @@ -138,11 +143,6 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: { editor = delegateIt->second->createEditor(dynamic_cast(mParent), QStyleOptionViewItem(), index, display); DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display); - if (display == CSMWorld::ColumnBase::Display_Boolean) - { - connect(editor, SIGNAL(stateChanged(int)), proxy, SLOT(editorDataCommited())); - } else - { if (hasEnums) //combox is used for all enums { connect(editor, SIGNAL(currentIndexChanged (int)), proxy, SLOT(editorDataCommited())); @@ -150,7 +150,6 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: { connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); } - } connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)), this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display))); mProxys.push_back(proxy); //deleted in the destructor } diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index 7e8cddd1f4..5da616ebb8 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -13,6 +13,7 @@ #include #include "../../model/world/commands.hpp" +#include CSVWorld::NastyTableModelHack::NastyTableModelHack (QAbstractItemModel& model) : mModel (model) @@ -126,18 +127,27 @@ void CSVWorld::CommandDelegate::setModelData (QWidget *editor, QAbstractItemMode QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const { - if (!(index.data(Qt::EditRole).isValid() or index.data(Qt::DisplayRole).isValid())) + QVariant variant = index.data(); + if (!variant.isValid()) { - return 0; + variant = index.data(Qt::DisplayRole); + if (!variant.isValid()) + { + return 0; + } } if (display != CSMWorld::ColumnBase::Display_None) { + if (variant.type() == QVariant::Color) + { + return new QLineEdit(parent); + } if (display == CSMWorld::ColumnBase::Display_Integer) { return new QSpinBox(parent); } - if (display == CSMWorld::ColumnBase::Display_Integer) + if (display == CSMWorld::ColumnBase::Display_Float) { return new QDoubleSpinBox(parent); } From cc96a38921c63645ca1f9e042c5d74d60f3b0635 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 10 Mar 2014 13:27:52 +0100 Subject: [PATCH 019/127] use qlinedit for the var --- apps/opencs/view/world/util.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index 5da616ebb8..14d5c89a0e 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -147,6 +147,10 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO { return new QSpinBox(parent); } + if (display == CSMWorld::ColumnBase::Display_Var) + { + return new QLineEdit(parent); + } if (display == CSMWorld::ColumnBase::Display_Float) { return new QDoubleSpinBox(parent); From 089732419a4ac40c688bc5b62c722843d8c17352 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 10 Mar 2014 14:11:49 +0100 Subject: [PATCH 020/127] introduce longString --- apps/opencs/model/world/columnbase.hpp | 1 + apps/opencs/model/world/columnimp.hpp | 4 +-- apps/opencs/view/world/dialoguesubview.cpp | 38 +++++++++++++++++----- apps/opencs/view/world/enumdelegate.cpp | 1 + apps/opencs/view/world/util.cpp | 19 +++++++++-- apps/opencs/view/world/util.hpp | 2 +- 6 files changed, 51 insertions(+), 14 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index d990232f70..fe310d0aa4 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -28,6 +28,7 @@ namespace CSMWorld { Display_None, //Do not use Display_String, + Display_LongString, //CONCRETE TYPES STARTS HERE Display_Skill, diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index def225018f..6311562a6a 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -202,7 +202,7 @@ namespace CSMWorld struct DescriptionColumn : public Column { DescriptionColumn() - : Column (Columns::ColumnId_Description, ColumnBase::Display_String) + : Column (Columns::ColumnId_Description, ColumnBase::Display_LongString) {} virtual QVariant get (const Record& record) const @@ -1380,7 +1380,7 @@ namespace CSMWorld template struct QuestDescriptionColumn : public Column { - QuestDescriptionColumn() : Column (Columns::ColumnId_QuestDescription, ColumnBase::Display_String) {} + QuestDescriptionColumn() : Column (Columns::ColumnId_QuestDescription, ColumnBase::Display_LongString) {} virtual QVariant get (const Record& record) const { diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 6a37ce59c9..1f6c411489 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -13,6 +13,10 @@ #include #include #include +#include +#include +#include +#include #include "../../model/world/columnbase.hpp" #include "../../model/world/idtable.hpp" @@ -126,30 +130,46 @@ QSize CSVWorld::DialogueDelegateDispatcher::sizeHint (const QStyleOptionViewItem QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase::Display display, const QModelIndex& index) { - bool hasEnums = CSMWorld::Columns::hasEnums(static_cast(mTable->getColumnId(index.column() ) ) ); QVariant variant = index.data(); if (!variant.isValid()) { variant = index.data(Qt::DisplayRole); if (!variant.isValid()) { - return 0; + return NULL; } } + QWidget* editor = NULL; std::map::iterator delegateIt(mDelegates.find(display)); if (delegateIt != mDelegates.end()) { editor = delegateIt->second->createEditor(dynamic_cast(mParent), QStyleOptionViewItem(), index, display); DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display); - if (hasEnums) //combox is used for all enums - { - connect(editor, SIGNAL(currentIndexChanged (int)), proxy, SLOT(editorDataCommited())); - } else - { - connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); - } + + bool skip = false; + if (qobject_cast(editor)) + { + connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); + skip = true; + } + if(!skip && qobject_cast(editor)) + { + connect(editor, SIGNAL(stateChanged(int)), proxy, SLOT(editorDataCommited())); + skip = true; + } + if(!skip && qobject_cast(editor)) + { + connect(editor, SIGNAL(textChanged()), proxy, SLOT(editorDataCommited())); + skip = true; + } + if(!skip && qobject_cast(editor)) + { + connect(editor, SIGNAL(currentIndexChanged (int)), proxy, SLOT(editorDataCommited())); + skip = true; + } + connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)), this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display))); mProxys.push_back(proxy); //deleted in the destructor } diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index 858458b37b..e5a766731e 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -9,6 +9,7 @@ #include #include "../../model/world/commands.hpp" +#include void CSVWorld::EnumDelegate::setModelDataImp (QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index 14d5c89a0e..f93edab3e2 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -11,6 +11,7 @@ #include #include #include +#include #include "../../model/world/commands.hpp" #include @@ -155,7 +156,11 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO { return new QDoubleSpinBox(parent); } - if (display == CSMWorld::ColumnBase::Display_String) + if (display == CSMWorld::ColumnBase::Display_LongString) + { + return new QTextEdit(parent); + } + if (display == CSMWorld::ColumnBase::Display_String || display == CSMWorld::ColumnBase::Display_Skill) { return new QLineEdit(parent); } @@ -185,7 +190,7 @@ bool CSVWorld::CommandDelegate::updateEditorSetting (const QString &settingName, return false; } -void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay) const +void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay) { QVariant v = index.data(Qt::EditRole); if (tryDisplay) @@ -198,7 +203,16 @@ void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelInde return; } } + QPlainTextEdit* plainTextEdit = qobject_cast(editor); + if(plainTextEdit) + { + if(plainTextEdit->toPlainText() == v.toString()) + { + return; + } + } } + QByteArray n = editor->metaObject()->userProperty().name(); if (n == "dateTime") { @@ -213,4 +227,5 @@ void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelInde v = QVariant(editor->property(n).userType(), (const void *)0); editor->setProperty(n, v); } + } \ No newline at end of file diff --git a/apps/opencs/view/world/util.hpp b/apps/opencs/view/world/util.hpp index 814f09d3a2..9b9d89535f 100644 --- a/apps/opencs/view/world/util.hpp +++ b/apps/opencs/view/world/util.hpp @@ -113,7 +113,7 @@ namespace CSVWorld virtual bool updateEditorSetting (const QString &settingName, const QString &settingValue); ///< \return Does column require update? - virtual void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay = false) const; + virtual void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay = false); private slots: From f4614c2c63af7e33a662f2266cf1f9ad0606ce40 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 10 Mar 2014 17:52:45 +0100 Subject: [PATCH 021/127] use qlabels for not editable fields --- apps/opencs/view/world/dialoguesubview.cpp | 35 ++++++++++++++++++++-- 1 file changed, 32 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 1f6c411489..251c2755ea 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -94,6 +94,31 @@ void CSVWorld::DialogueDelegateDispatcher::setEditorData (QWidget* editor, const CSMWorld::ColumnBase::Display display = static_cast (mTable->headerData (index.column(), Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); + QLabel* label = qobject_cast(editor); + if(label) + { + QVariant v = index.data(Qt::EditRole); + if (!v.isValid()) + { + v = index.data(Qt::DisplayRole); + if (!v.isValid()) + { + return; + } + } + if (CSMWorld::Columns::hasEnums(static_cast(mTable->getColumnId(index.column())))) + { + int data = v.toInt(); + std::vector enumNames (CSMWorld::Columns::getEnums (static_cast (mTable->getColumnId (index.column())))); + label->setText(QString::fromUtf8(enumNames.at(data).c_str())); + } else + { + label->clear(); + label->setText(v.toString()); + } + return; + } + std::map::const_iterator delegateIt(mDelegates.find(display)); if (delegateIt != mDelegates.end()) { @@ -140,12 +165,17 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: } } - QWidget* editor = NULL; + if (! (mTable->flags (index) & Qt::ItemIsEditable)) + { + editor = new QLabel(qobject_cast(mParent)); + return editor; + } + std::map::iterator delegateIt(mDelegates.find(display)); if (delegateIt != mDelegates.end()) { - editor = delegateIt->second->createEditor(dynamic_cast(mParent), QStyleOptionViewItem(), index, display); + editor = delegateIt->second->createEditor(qobject_cast(mParent), QStyleOptionViewItem(), index, display); DialogueDelegateDispatcherProxy* proxy = new DialogueDelegateDispatcherProxy(editor, display); bool skip = false; @@ -247,7 +277,6 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM editor->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); if (! (model->flags (model->index (0, i)) & Qt::ItemIsEditable)) { - editor->setDisabled(true); lockedLayout->addWidget (label, locked, 0); lockedLayout->addWidget (editor, locked, 1); ++locked; From 17b521cec8155264c10e293e3aada7f56075b853 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 10 Mar 2014 17:57:40 +0100 Subject: [PATCH 022/127] additional check --- apps/opencs/view/world/dialoguesubview.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 251c2755ea..5c083f8810 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -113,8 +113,10 @@ void CSVWorld::DialogueDelegateDispatcher::setEditorData (QWidget* editor, const label->setText(QString::fromUtf8(enumNames.at(data).c_str())); } else { - label->clear(); - label->setText(v.toString()); + if (QVariant::String == v.type()) + { + label->setText(v.toString()); + } } return; } From ef1364878fc98876726759911a18b97ee5b6965e Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 10 Mar 2014 18:35:49 +0100 Subject: [PATCH 023/127] moved test cube from SceneWidget to WorldspaceWidget --- apps/opencs/view/render/scenewidget.cpp | 10 +++++----- apps/opencs/view/render/scenewidget.hpp | 2 ++ apps/opencs/view/render/worldspacewidget.cpp | 11 ++++++++++- 3 files changed, 17 insertions(+), 6 deletions(-) diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 31d5d03187..7b790fd581 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -45,11 +45,6 @@ namespace CSVRender mCamera = mSceneMgr->createCamera("foo"); - Ogre::Entity* ent = mSceneMgr->createEntity("cube", Ogre::SceneManager::PT_CUBE); - ent->setMaterialName("BaseWhite"); - - mSceneMgr->getRootSceneNode()->attachObject(ent); - mCamera->setPosition(300,300,300); mCamera->lookAt(0,0,0); mCamera->setNearClipDistance(0.1); @@ -118,6 +113,11 @@ namespace CSVRender } } + Ogre::SceneManager *SceneWidget::getSceneManager() + { + return mSceneMgr; + } + void SceneWidget::paintEvent(QPaintEvent* e) { if (!mWindow) diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index ad68897ac0..05b06b2873 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -34,6 +34,8 @@ namespace CSVRender void setNavigation (Navigation *navigation); ///< \attention The ownership of \a navigation is not transferred to *this. + Ogre::SceneManager *getSceneManager(); + private: void paintEvent(QPaintEvent* e); void resizeEvent(QResizeEvent* e); diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index dcd152bb33..9959c5a673 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -1,11 +1,20 @@ #include "worldspacewidget.hpp" +#include +#include +#include + #include "../world/scenetoolmode.hpp" CSVRender::WorldspaceWidget::WorldspaceWidget (QWidget *parent) : SceneWidget (parent) -{} +{ + Ogre::Entity* ent = getSceneManager()->createEntity("cube", Ogre::SceneManager::PT_CUBE); + ent->setMaterialName("BaseWhite"); + + getSceneManager()->getRootSceneNode()->attachObject(ent); +} void CSVRender::WorldspaceWidget::selectNavigationMode (const std::string& mode) { From a25271f0b61055c66d9f17ab05a88a0cd5868afd Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 11 Mar 2014 09:14:13 +0100 Subject: [PATCH 024/127] moving bloat away from the dispatcher --- apps/opencs/view/world/dialoguesubview.cpp | 81 +++++++++++++++------- apps/opencs/view/world/dialoguesubview.hpp | 24 +++++++ apps/opencs/view/world/util.cpp | 4 +- apps/opencs/view/world/util.hpp | 2 +- 4 files changed, 84 insertions(+), 27 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 5c083f8810..65db33cbfc 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -24,6 +24,59 @@ #include "recordstatusdelegate.hpp" #include "util.hpp" +/* +==============================NotEditableSubDelegate========================================== +*/ +CSVWorld::NotEditableSubDelegate::NotEditableSubDelegate(const CSMWorld::IdTable* table, QObject * parent) : +QAbstractItemDelegate(parent), +mTable(table) +{} + +void CSVWorld::NotEditableSubDelegate::setEditorData (QLabel* editor, const QModelIndex& index) const +{ + QVariant v = index.data(Qt::EditRole); + if (!v.isValid()) + { + v = index.data(Qt::DisplayRole); + if (!v.isValid()) + { + return; + } + } + + if (QVariant::String == v.type()) + { + editor->setText(v.toString()); + } else //else we are facing enums + { + int data = v.toInt(); + std::vector enumNames (CSMWorld::Columns::getEnums (static_cast (mTable->getColumnId (index.column())))); + editor->setText(QString::fromUtf8(enumNames.at(data).c_str())); + } +} + +void CSVWorld::NotEditableSubDelegate::setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const +{ + //not editable widgets will not save model data +} + +void CSVWorld::NotEditableSubDelegate::paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + //does nothing +} + +QSize CSVWorld::NotEditableSubDelegate::sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const +{ + return QSize(); +} + +QWidget* CSVWorld::NotEditableSubDelegate::createEditor (QWidget *parent, + const QStyleOptionViewItem& option, + const QModelIndex& index, + CSMWorld::ColumnBase::Display display) const +{ + return new QLabel(parent); +} /* ==============================DialogueDelegateDispatcherProxy========================================== @@ -64,7 +117,8 @@ QWidget* CSVWorld::DialogueDelegateDispatcherProxy::getEditor() const CSVWorld::DialogueDelegateDispatcher::DialogueDelegateDispatcher(QObject* parent, CSMWorld::IdTable* table, QUndoStack& undoStack) : mParent(parent), mTable(table), -mUndoStack(undoStack) +mUndoStack(undoStack), +mNotEditableDelegate(table, parent) { } @@ -97,27 +151,7 @@ void CSVWorld::DialogueDelegateDispatcher::setEditorData (QWidget* editor, const QLabel* label = qobject_cast(editor); if(label) { - QVariant v = index.data(Qt::EditRole); - if (!v.isValid()) - { - v = index.data(Qt::DisplayRole); - if (!v.isValid()) - { - return; - } - } - if (CSMWorld::Columns::hasEnums(static_cast(mTable->getColumnId(index.column())))) - { - int data = v.toInt(); - std::vector enumNames (CSMWorld::Columns::getEnums (static_cast (mTable->getColumnId (index.column())))); - label->setText(QString::fromUtf8(enumNames.at(data).c_str())); - } else - { - if (QVariant::String == v.type()) - { - label->setText(v.toString()); - } - } + mNotEditableDelegate.setEditorData(label, index); return; } @@ -170,8 +204,7 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: QWidget* editor = NULL; if (! (mTable->flags (index) & Qt::ItemIsEditable)) { - editor = new QLabel(qobject_cast(mParent)); - return editor; + return mNotEditableDelegate.createEditor(qobject_cast(mParent), QStyleOptionViewItem(), index, display); } std::map::iterator delegateIt(mDelegates.find(display)); diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 06c849e390..33514d205a 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -12,6 +12,7 @@ class QDataWidgetMapper; class QSize; class QEvent; +class QLabel; namespace CSMWorld { @@ -27,6 +28,27 @@ namespace CSVWorld { class CommandDelegate; + class NotEditableSubDelegate : public QAbstractItemDelegate + { + const CSMWorld::IdTable* mTable; + public: + NotEditableSubDelegate(const CSMWorld::IdTable* table, QObject * parent = 0); + + virtual void setEditorData (QLabel* editor, const QModelIndex& index) const; + + virtual void setModelData (QWidget* editor, QAbstractItemModel* model, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const; + + virtual void paint (QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index) const; + ///< does nothing + + virtual QSize sizeHint (const QStyleOptionViewItem& option, const QModelIndex& index) const; + ///< does nothing + + virtual QWidget *createEditor (QWidget *parent, + const QStyleOptionViewItem& option, + const QModelIndex& index, + CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None) const; + }; //this can't be nested into the DialogueDelegateDispatcher, because it needs to emit signals class DialogueDelegateDispatcherProxy : public QObject @@ -68,6 +90,8 @@ namespace CSVWorld QUndoStack& mUndoStack; + NotEditableSubDelegate mNotEditableDelegate; + std::vector mProxys; //once we move to the C++11 we should use unique_ptr public: diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index f93edab3e2..3635ee1d40 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -190,7 +190,7 @@ bool CSVWorld::CommandDelegate::updateEditorSetting (const QString &settingName, return false; } -void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay) +void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay) const { QVariant v = index.data(Qt::EditRole); if (tryDisplay) @@ -204,7 +204,7 @@ void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelInde } } QPlainTextEdit* plainTextEdit = qobject_cast(editor); - if(plainTextEdit) + if(plainTextEdit) //for some reason it is easier to brake the loop here { if(plainTextEdit->toPlainText() == v.toString()) { diff --git a/apps/opencs/view/world/util.hpp b/apps/opencs/view/world/util.hpp index 9b9d89535f..814f09d3a2 100644 --- a/apps/opencs/view/world/util.hpp +++ b/apps/opencs/view/world/util.hpp @@ -113,7 +113,7 @@ namespace CSVWorld virtual bool updateEditorSetting (const QString &settingName, const QString &settingValue); ///< \return Does column require update? - virtual void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay = false); + virtual void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay = false) const; private slots: From 87286232d71c70f01e4d045f645c546daf78739e Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 11 Mar 2014 09:38:53 +0100 Subject: [PATCH 025/127] fixed bug, god bless overloading --- apps/opencs/view/world/enumdelegate.cpp | 19 +++++++++++++++++-- apps/opencs/view/world/enumdelegate.hpp | 4 ++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index e5a766731e..40f447f9ea 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -14,7 +14,7 @@ void CSVWorld::EnumDelegate::setModelDataImp (QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const { - if (QComboBox *comboBox = dynamic_cast (editor)) + if (QComboBox *comboBox = qobject_cast (editor)) { QString value = comboBox->currentText(); @@ -57,9 +57,24 @@ QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptio return comboBox; } +QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option, + const QModelIndex& index) const +{ + if (!index.data(Qt::EditRole).isValid()) + return 0; + + QComboBox *comboBox = new QComboBox (parent); + + for (std::vector >::const_iterator iter (mValues.begin()); + iter!=mValues.end(); ++iter) + comboBox->addItem (iter->second); + + return comboBox; +} + void CSVWorld::EnumDelegate::setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay) const { - if (QComboBox *comboBox = dynamic_cast (editor)) + if (QComboBox *comboBox = qobject_cast (editor)) //qobject_cast is faster than dynamic_cast { QVariant data = index.data (Qt::EditRole); diff --git a/apps/opencs/view/world/enumdelegate.hpp b/apps/opencs/view/world/enumdelegate.hpp index 8bd96a6f20..e3ecc051db 100644 --- a/apps/opencs/view/world/enumdelegate.hpp +++ b/apps/opencs/view/world/enumdelegate.hpp @@ -36,6 +36,10 @@ namespace CSVWorld const QModelIndex& index, CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None) const; + virtual QWidget *createEditor(QWidget *parent, + const QStyleOptionViewItem& option, + const QModelIndex& index) const; + virtual void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay = false) const; virtual void paint (QPainter *painter, const QStyleOptionViewItem& option, From 1edf5a4414863289f6cf2c415f698647057dfd1e Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 11 Mar 2014 10:47:30 +0100 Subject: [PATCH 026/127] registered additional subviews. --- apps/opencs/view/world/subviews.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 2fa2fc06be..d4d9565a4a 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -87,7 +87,14 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) manager.add(CSMWorld::UniversalId::Type_Gmst, new CSVDoc::SubViewFactory); manager.add(CSMWorld::UniversalId::Type_Race, new CSVDoc::SubViewFactory); manager.add(CSMWorld::UniversalId::Type_Class, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_Topic, new CSVDoc::SubViewFactory); manager.add(CSMWorld::UniversalId::Type_Reference, new CSVDoc::SubViewFactory); manager.add(CSMWorld::UniversalId::Type_Cell, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Filter, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Sound, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Faction, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Skill, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_JournalInfo, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_TopicInfo, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Topic, new CSVDoc::SubViewFactory); + manager.add(CSMWorld::UniversalId::Type_Journal, new CSVDoc::SubViewFactory); } \ No newline at end of file From 5ad572346b8e7f2f5f1f9fb42c4d2906526c7375 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 11 Mar 2014 13:02:25 +0100 Subject: [PATCH 027/127] referencables also work now --- apps/opencs/view/doc/view.cpp | 12 ++++++++++-- apps/opencs/view/world/util.cpp | 4 +++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index de3f476af1..bc34c6118e 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -316,8 +316,16 @@ void CSVDoc::View::addSubView (const CSMWorld::UniversalId& id, const std::strin /// \todo add an user setting to reuse sub views (on a per document basis or on a per top level view basis) - SubView *view = mSubViewFactory.makeSubView (id, *mDocument); - + const std::vector referenceables(CSMWorld::UniversalId::listReferenceableTypes()); + SubView *view = NULL; + if(std::find(referenceables.begin(), referenceables.end(), id.getType()) != referenceables.end()) + { + view = mSubViewFactory.makeSubView (CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Referenceable, id.getId()), *mDocument); + } else + { + view = mSubViewFactory.makeSubView (id, *mDocument); + } + assert(view); if (!hint.empty()) view->useHint (hint); diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index 3635ee1d40..766323d0b3 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -160,7 +160,9 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO { return new QTextEdit(parent); } - if (display == CSMWorld::ColumnBase::Display_String || display == CSMWorld::ColumnBase::Display_Skill) + if (display == CSMWorld::ColumnBase::Display_String || + display == CSMWorld::ColumnBase::Display_Skill || + display == CSMWorld::ColumnBase::Display_Script) { return new QLineEdit(parent); } From 81f32976e3a17d773de1e06ca6c970d9c29196d2 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 11 Mar 2014 18:38:37 +0100 Subject: [PATCH 028/127] changes --- apps/opencs/view/world/dialoguesubview.cpp | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 65db33cbfc..85cb946771 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -260,6 +260,10 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mDispatcher(this, dynamic_cast(document.getData().getTableModel (id)), document.getUndoStack()) { + CSMWorld::IdTable* model = dynamic_cast(document.getData().getTableModel (id)); + const QModelIndex indexToFocus(model->getModelIndex (id.getId(), 0)); + const int focusedRow = indexToFocus.row(); + QWidget *widget = new QWidget (this); setWidget (widget); @@ -280,9 +284,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM widget->setLayout (mainLayout); - QAbstractItemModel *model = document.getData().getTableModel (id); - - int columns = model->columnCount(); + const int columns = model->columnCount(); mWidgetMapper = new QDataWidgetMapper (this); mWidgetMapper->setModel (model); @@ -301,7 +303,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM (model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); mDispatcher.makeDelegate(display); - QWidget *editor = mDispatcher.makeEditor(display, (model->index (0, i))); + QWidget *editor = mDispatcher.makeEditor(display, (model->index (focusedRow, i))); if (editor) { @@ -325,8 +327,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM } } - mWidgetMapper->setCurrentModelIndex ( - dynamic_cast (*model).getModelIndex (id.getId(), 0)); + mWidgetMapper->setCurrentModelIndex (indexToFocus); } void CSVWorld::DialogueSubView::setEditLock (bool locked) From c422dc6eed94f9e8f283c9e41cea5019b3b079ea Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 11 Mar 2014 18:38:37 +0100 Subject: [PATCH 029/127] Refactorisation. --- apps/opencs/view/world/dialoguesubview.cpp | 13 ++++++----- apps/opencs/view/world/enumdelegate.cpp | 27 ++++++++-------------- apps/opencs/view/world/enumdelegate.hpp | 7 +++--- 3 files changed, 21 insertions(+), 26 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 65db33cbfc..85cb946771 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -260,6 +260,10 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mDispatcher(this, dynamic_cast(document.getData().getTableModel (id)), document.getUndoStack()) { + CSMWorld::IdTable* model = dynamic_cast(document.getData().getTableModel (id)); + const QModelIndex indexToFocus(model->getModelIndex (id.getId(), 0)); + const int focusedRow = indexToFocus.row(); + QWidget *widget = new QWidget (this); setWidget (widget); @@ -280,9 +284,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM widget->setLayout (mainLayout); - QAbstractItemModel *model = document.getData().getTableModel (id); - - int columns = model->columnCount(); + const int columns = model->columnCount(); mWidgetMapper = new QDataWidgetMapper (this); mWidgetMapper->setModel (model); @@ -301,7 +303,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM (model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); mDispatcher.makeDelegate(display); - QWidget *editor = mDispatcher.makeEditor(display, (model->index (0, i))); + QWidget *editor = mDispatcher.makeEditor(display, (model->index (focusedRow, i))); if (editor) { @@ -325,8 +327,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM } } - mWidgetMapper->setCurrentModelIndex ( - dynamic_cast (*model).getModelIndex (id.getId(), 0)); + mWidgetMapper->setCurrentModelIndex (indexToFocus); } void CSVWorld::DialogueSubView::setEditLock (bool locked) diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index 40f447f9ea..6c46232a89 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -14,7 +14,7 @@ void CSVWorld::EnumDelegate::setModelDataImp (QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const { - if (QComboBox *comboBox = qobject_cast (editor)) + if (QComboBox *comboBox = dynamic_cast (editor)) { QString value = comboBox->currentText(); @@ -42,6 +42,14 @@ CSVWorld::EnumDelegate::EnumDelegate (const std::vector } +QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, + const QStyleOptionViewItem& option, + const QModelIndex& index) const +{ + return createEditor(parent, option, index, CSMWorld::ColumnBase::Display_None); + //overloading virtual functions is HARD +} + QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option, const QModelIndex& index, CSMWorld::ColumnBase::Display display) const { @@ -57,24 +65,9 @@ QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptio return comboBox; } -QWidget *CSVWorld::EnumDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem& option, - const QModelIndex& index) const -{ - if (!index.data(Qt::EditRole).isValid()) - return 0; - - QComboBox *comboBox = new QComboBox (parent); - - for (std::vector >::const_iterator iter (mValues.begin()); - iter!=mValues.end(); ++iter) - comboBox->addItem (iter->second); - - return comboBox; -} - void CSVWorld::EnumDelegate::setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay) const { - if (QComboBox *comboBox = qobject_cast (editor)) //qobject_cast is faster than dynamic_cast + if (QComboBox *comboBox = dynamic_cast (editor)) { QVariant data = index.data (Qt::EditRole); diff --git a/apps/opencs/view/world/enumdelegate.hpp b/apps/opencs/view/world/enumdelegate.hpp index e3ecc051db..cd749a4518 100644 --- a/apps/opencs/view/world/enumdelegate.hpp +++ b/apps/opencs/view/world/enumdelegate.hpp @@ -4,6 +4,7 @@ #include #include +#include #include @@ -33,12 +34,12 @@ namespace CSVWorld virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem& option, - const QModelIndex& index, - CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None) const; + const QModelIndex& index) const; virtual QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem& option, - const QModelIndex& index) const; + const QModelIndex& index, + CSMWorld::ColumnBase::Display display = CSMWorld::ColumnBase::Display_None) const; virtual void setEditorData (QWidget *editor, const QModelIndex& index, bool tryDisplay = false) const; From 865e6b52ae62d4e1b8541e10ea47dcc418766682 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 11 Mar 2014 21:21:05 +0100 Subject: [PATCH 030/127] scroll area --- apps/opencs/view/world/dialoguesubview.cpp | 11 ++++++++--- apps/opencs/view/world/util.cpp | 5 ++++- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 85cb946771..6a3e1d25d2 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include "../../model/world/columnbase.hpp" #include "../../model/world/idtable.hpp" @@ -264,9 +265,8 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM const QModelIndex indexToFocus(model->getModelIndex (id.getId(), 0)); const int focusedRow = indexToFocus.row(); - QWidget *widget = new QWidget (this); - - setWidget (widget); + QScrollArea *scrollArea = new QScrollArea(this); + QWidget *widget = new QWidget (scrollArea); QFrame* line = new QFrame(this); line->setObjectName(QString::fromUtf8("line")); @@ -328,6 +328,11 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM } mWidgetMapper->setCurrentModelIndex (indexToFocus); + + scrollArea->setMinimumWidth(250); + scrollArea->setWidget(widget); + scrollArea->setWidgetResizable(true); + setWidget (scrollArea); } void CSVWorld::DialogueSubView::setEditLock (bool locked) diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index 766323d0b3..85d8392ffe 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -162,7 +162,10 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO } if (display == CSMWorld::ColumnBase::Display_String || display == CSMWorld::ColumnBase::Display_Skill || - display == CSMWorld::ColumnBase::Display_Script) + display == CSMWorld::ColumnBase::Display_Script || + display == CSMWorld::ColumnBase::Display_Race || + display == CSMWorld::ColumnBase::Display_Class || + display == CSMWorld::ColumnBase::Display_Faction) { return new QLineEdit(parent); } From 8d50af547a1434d9aea71c73109de21c3ac9a9e2 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 12 Mar 2014 10:21:52 +0100 Subject: [PATCH 031/127] created editwidget --- apps/opencs/view/world/dialoguesubview.cpp | 91 +++++++++++++--------- apps/opencs/view/world/dialoguesubview.hpp | 15 +++- 2 files changed, 70 insertions(+), 36 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 6a3e1d25d2..dd38e770f9 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -251,68 +251,75 @@ CSVWorld::DialogueDelegateDispatcher::~DialogueDelegateDispatcher() } /* -==============================DialogueSubView========================================== +=============================================================EditWidget===================================================== */ -CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, - bool createAndDelete) : - - SubView (id), - mDispatcher(this, dynamic_cast(document.getData().getTableModel (id)), document.getUndoStack()) - +CSVWorld::EditWidget::EditWidget(QWidget *parent, const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete) : +mDispatcher(this, dynamic_cast(document.getData().getTableModel (id)), document.getUndoStack()), +QScrollArea(parent), +mWidgetMapper(NULL), +mMainWidget(NULL), +mUndoStack(document.getUndoStack()), +mTable(dynamic_cast(document.getData().getTableModel(id))) { - CSMWorld::IdTable* model = dynamic_cast(document.getData().getTableModel (id)); - const QModelIndex indexToFocus(model->getModelIndex (id.getId(), 0)); - const int focusedRow = indexToFocus.row(); + remake (id); +} - QScrollArea *scrollArea = new QScrollArea(this); - QWidget *widget = new QWidget (scrollArea); +void CSVWorld::EditWidget::remake(const CSMWorld::UniversalId& id) +{ + const QModelIndex indexToFocus(mTable->getModelIndex (id.getId(), 0)); - QFrame* line = new QFrame(this); + if (mMainWidget) + { + delete mMainWidget; + } + mMainWidget = new QWidget (this); + + if (mWidgetMapper) + { + delete mWidgetMapper; + } + mWidgetMapper = new QDataWidgetMapper (this); + mWidgetMapper->setModel(mTable); + mWidgetMapper->setItemDelegate(&mDispatcher); + + QFrame* line = new QFrame(mMainWidget); line->setObjectName(QString::fromUtf8("line")); line->setGeometry(QRect(320, 150, 118, 3)); line->setFrameShape(QFrame::HLine); line->setFrameShadow(QFrame::Sunken); - QVBoxLayout *mainLayout = new QVBoxLayout; - QGridLayout *unlockedLayout = new QGridLayout; - QGridLayout *lockedLayout = new QGridLayout; + QVBoxLayout *mainLayout = new QVBoxLayout(mMainWidget); + QGridLayout *unlockedLayout = new QGridLayout(); + QGridLayout *lockedLayout = new QGridLayout(); mainLayout->addLayout(lockedLayout, 0); mainLayout->addWidget(line, 1); mainLayout->addLayout(unlockedLayout, 2); mainLayout->addStretch(1); - widget->setLayout (mainLayout); - - const int columns = model->columnCount(); - - mWidgetMapper = new QDataWidgetMapper (this); - mWidgetMapper->setModel (model); - mWidgetMapper->setItemDelegate(&mDispatcher); - int unlocked = 0; int locked = 0; - std::vector editors; + const int focusedRow = indexToFocus.row(); + const int columns = mTable->columnCount(); for (int i=0; iheaderData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt(); + int flags = mTable->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Flags).toInt(); if (flags & CSMWorld::ColumnBase::Flag_Dialogue) { CSMWorld::ColumnBase::Display display = static_cast - (model->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); + (mTable->headerData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); mDispatcher.makeDelegate(display); - QWidget *editor = mDispatcher.makeEditor(display, (model->index (focusedRow, i))); + QWidget *editor = mDispatcher.makeEditor(display, (mTable->index (focusedRow, i))); if (editor) { - editors.push_back(editor); mWidgetMapper->addMapping (editor, i); - QLabel* label = new QLabel(model->headerData (i, Qt::Horizontal).toString()); + QLabel* label = new QLabel(mTable->headerData (i, Qt::Horizontal).toString(), mMainWidget); label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); editor->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - if (! (model->flags (model->index (0, i)) & Qt::ItemIsEditable)) + if (! (mTable->flags (mTable->index (0, i)) & Qt::ItemIsEditable)) { lockedLayout->addWidget (label, locked, 0); lockedLayout->addWidget (editor, locked, 1); @@ -329,10 +336,24 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mWidgetMapper->setCurrentModelIndex (indexToFocus); - scrollArea->setMinimumWidth(250); - scrollArea->setWidget(widget); - scrollArea->setWidgetResizable(true); - setWidget (scrollArea); + this->setMinimumWidth(300); + this->setWidget(mMainWidget); + this->setWidgetResizable(true); +} + +/* +==============================DialogueSubView========================================== +*/ + +CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, + bool createAndDelete) : + + SubView (id) + +{ + EditWidget* widget = new EditWidget(this, id, document, false); + + setWidget (widget); } void CSVWorld::DialogueSubView::setEditLock (bool locked) diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 33514d205a..40c658b9e4 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -5,6 +5,7 @@ #include #include +#include #include "../doc/subview.hpp" #include "../../model/world/columnbase.hpp" @@ -119,11 +120,23 @@ namespace CSVWorld }; - class DialogueSubView : public CSVDoc::SubView + class EditWidget : public QScrollArea { QDataWidgetMapper *mWidgetMapper; DialogueDelegateDispatcher mDispatcher; + QWidget* mMainWidget; + CSMWorld::IdTable* mTable; + QUndoStack& mUndoStack; + public: + + EditWidget (QWidget *parent, const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete = false); + + void remake(const CSMWorld::UniversalId& id); + }; + + class DialogueSubView : public CSVDoc::SubView + { public: DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete = false); From 299b7a6ce6de170aba94a853d7a4bc28e478781d Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 12 Mar 2014 11:08:04 +0100 Subject: [PATCH 032/127] Added buttons, they don't do anything. --- apps/opencs/view/world/dialoguesubview.cpp | 20 +++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index dd38e770f9..e34d744d93 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -18,6 +18,7 @@ #include #include #include +#include #include "../../model/world/columnbase.hpp" #include "../../model/world/idtable.hpp" @@ -317,7 +318,7 @@ void CSVWorld::EditWidget::remake(const CSMWorld::UniversalId& id) { mWidgetMapper->addMapping (editor, i); QLabel* label = new QLabel(mTable->headerData (i, Qt::Horizontal).toString(), mMainWidget); - label->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Fixed); + label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); editor->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); if (! (mTable->flags (mTable->index (0, i)) & Qt::ItemIsEditable)) { @@ -351,9 +352,22 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM SubView (id) { - EditWidget* widget = new EditWidget(this, id, document, false); + QWidget *mainWidget = new QWidget(this); + + QHBoxLayout *buttonsLayout = new QHBoxLayout; + QPushButton* mPrevButton = new QPushButton(tr("Previous")); + QPushButton* mNextButton = new QPushButton(tr("Next")); + buttonsLayout->addWidget(mPrevButton); + buttonsLayout->addWidget(mNextButton); + + QVBoxLayout *mainLayout = new QVBoxLayout(mainWidget); + + EditWidget* editWidget = new EditWidget(mainWidget, id, document, false); + mainLayout->addLayout(buttonsLayout); + mainLayout->addWidget(editWidget); + editWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + setWidget(mainWidget); - setWidget (widget); } void CSVWorld::DialogueSubView::setEditLock (bool locked) From cb9bcc3cc118dbbbe9f4569f4c9d15562cef8dbb Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 12 Mar 2014 12:25:37 +0100 Subject: [PATCH 033/127] buttons are functional --- apps/opencs/view/world/dialoguesubview.cpp | 85 ++++++++++++++++------ apps/opencs/view/world/dialoguesubview.hpp | 19 ++++- apps/opencs/view/world/enumdelegate.cpp | 1 - 3 files changed, 81 insertions(+), 24 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index e34d744d93..212031a017 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -255,21 +255,19 @@ CSVWorld::DialogueDelegateDispatcher::~DialogueDelegateDispatcher() =============================================================EditWidget===================================================== */ -CSVWorld::EditWidget::EditWidget(QWidget *parent, const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete) : -mDispatcher(this, dynamic_cast(document.getData().getTableModel (id)), document.getUndoStack()), +CSVWorld::EditWidget::EditWidget(QWidget *parent, int row, CSMWorld::IdTable* table, QUndoStack& undoStack, bool createAndDelete) : +mDispatcher(this, table, undoStack), QScrollArea(parent), mWidgetMapper(NULL), mMainWidget(NULL), -mUndoStack(document.getUndoStack()), -mTable(dynamic_cast(document.getData().getTableModel(id))) +mUndoStack(undoStack), +mTable(table) { - remake (id); + remake (row); } -void CSVWorld::EditWidget::remake(const CSMWorld::UniversalId& id) +void CSVWorld::EditWidget::remake(int row) { - const QModelIndex indexToFocus(mTable->getModelIndex (id.getId(), 0)); - if (mMainWidget) { delete mMainWidget; @@ -300,7 +298,6 @@ void CSVWorld::EditWidget::remake(const CSMWorld::UniversalId& id) int unlocked = 0; int locked = 0; - const int focusedRow = indexToFocus.row(); const int columns = mTable->columnCount(); for (int i=0; iheaderData (i, Qt::Horizontal, CSMWorld::ColumnBase::Role_Display).toInt()); mDispatcher.makeDelegate(display); - QWidget *editor = mDispatcher.makeEditor(display, (mTable->index (focusedRow, i))); + QWidget *editor = mDispatcher.makeEditor(display, (mTable->index (row, i))); if (editor) { @@ -335,7 +332,7 @@ void CSVWorld::EditWidget::remake(const CSMWorld::UniversalId& id) } } - mWidgetMapper->setCurrentModelIndex (indexToFocus); + mWidgetMapper->setCurrentModelIndex(mTable->index(row, 0)); this->setMinimumWidth(300); this->setWidget(mMainWidget); @@ -349,25 +346,71 @@ void CSVWorld::EditWidget::remake(const CSMWorld::UniversalId& id) CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete) : - SubView (id) + SubView (id), + mEditWidget(0), + mMainLayout(NULL), + mUndoStack(document.getUndoStack()), + mTable(dynamic_cast(document.getData().getTableModel(id))), + mRow (-1) { + mRow = mTable->getModelIndex (id.getId(), 0).row(); QWidget *mainWidget = new QWidget(this); QHBoxLayout *buttonsLayout = new QHBoxLayout; - QPushButton* mPrevButton = new QPushButton(tr("Previous")); - QPushButton* mNextButton = new QPushButton(tr("Next")); - buttonsLayout->addWidget(mPrevButton); - buttonsLayout->addWidget(mNextButton); + QPushButton* prevButton = new QPushButton(tr("Previous"), mainWidget); + QPushButton* nextButton = new QPushButton(tr("Next"), mainWidget); + buttonsLayout->addWidget(prevButton); + buttonsLayout->addWidget(nextButton); + connect(nextButton, SIGNAL(clicked()), this, SLOT(nextId())); + connect(prevButton, SIGNAL(clicked()), this, SLOT(prevId())); - QVBoxLayout *mainLayout = new QVBoxLayout(mainWidget); + mMainLayout = new QVBoxLayout(mainWidget); + + mEditWidget = new EditWidget(mainWidget, mRow, mTable, mUndoStack, false); + mMainLayout->addLayout(buttonsLayout); + mMainLayout->addWidget(mEditWidget); + mEditWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); - EditWidget* editWidget = new EditWidget(mainWidget, id, document, false); - mainLayout->addLayout(buttonsLayout); - mainLayout->addWidget(editWidget); - editWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); setWidget(mainWidget); +} +void CSVWorld::DialogueSubView::prevId() +{ + if (mRow < 1) + { + return; + } + + int newRow = mRow - 1; + QModelIndex newIndex(mTable->index(newRow, 0)); + + if (!newIndex.isValid()) + { + return; + } + + mEditWidget->remake(newRow); + mRow = newRow; +} + +void CSVWorld::DialogueSubView::nextId() +{ + if (mRow == -1) + { + return; + } + + int newRow = mRow + 1; + QModelIndex newIndex(mTable->index(newRow, 0)); + + if (!newIndex.isValid()) + { + return; + } + + mEditWidget->remake(newRow); + mRow = newRow; } void CSVWorld::DialogueSubView::setEditLock (bool locked) diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 40c658b9e4..0576c7aff7 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -14,6 +14,7 @@ class QDataWidgetMapper; class QSize; class QEvent; class QLabel; +class QVBoxLayout; namespace CSMWorld { @@ -130,18 +131,32 @@ namespace CSVWorld public: - EditWidget (QWidget *parent, const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete = false); + EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table, QUndoStack& undoStack, bool createAndDelete = false); - void remake(const CSMWorld::UniversalId& id); + void remake(int row); }; class DialogueSubView : public CSVDoc::SubView { + Q_OBJECT + + EditWidget* mEditWidget; + QVBoxLayout* mMainLayout; + CSMWorld::IdTable* mTable; + QUndoStack& mUndoStack; + int mRow; + public: DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete = false); virtual void setEditLock (bool locked); + + private slots: + + void nextId(); + + void prevId(); }; } diff --git a/apps/opencs/view/world/enumdelegate.cpp b/apps/opencs/view/world/enumdelegate.cpp index 6c46232a89..377f479bff 100644 --- a/apps/opencs/view/world/enumdelegate.cpp +++ b/apps/opencs/view/world/enumdelegate.cpp @@ -9,7 +9,6 @@ #include #include "../../model/world/commands.hpp" -#include void CSVWorld::EnumDelegate::setModelDataImp (QWidget *editor, QAbstractItemModel *model, const QModelIndex& index) const From 2e226e63b696223a4061bc9f0ed5354a4bdc2b43 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 12 Mar 2014 13:04:40 +0100 Subject: [PATCH 034/127] change universalid of base subview after pressing next or prev --- apps/opencs/view/doc/subview.cpp | 8 +++++++- apps/opencs/view/doc/subview.hpp | 2 ++ apps/opencs/view/world/dialoguesubview.cpp | 4 ++++ 3 files changed, 13 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/doc/subview.cpp b/apps/opencs/view/doc/subview.cpp index 6160f2673c..dcd85945fc 100644 --- a/apps/opencs/view/doc/subview.cpp +++ b/apps/opencs/view/doc/subview.cpp @@ -18,4 +18,10 @@ void CSVDoc::SubView::updateEditorSetting (const QString &settingName, const QSt void CSVDoc::SubView::setStatusBar (bool show) {} -void CSVDoc::SubView::useHint (const std::string& hint) {} \ No newline at end of file +void CSVDoc::SubView::useHint (const std::string& hint) {} + +void CSVDoc::SubView::setUniversalId (const CSMWorld::UniversalId& id) +{ + mUniversalId = id; + setWindowTitle (mUniversalId.toString().c_str()); +} \ No newline at end of file diff --git a/apps/opencs/view/doc/subview.hpp b/apps/opencs/view/doc/subview.hpp index 59781f869c..85274a18db 100644 --- a/apps/opencs/view/doc/subview.hpp +++ b/apps/opencs/view/doc/subview.hpp @@ -27,6 +27,8 @@ namespace CSVDoc // not implemented SubView (const SubView&); SubView& operator= (SubView&); + protected: + void setUniversalId(const CSMWorld::UniversalId& id); public: diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 212031a017..f8cb81a8ff 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -391,6 +391,8 @@ void CSVWorld::DialogueSubView::prevId() } mEditWidget->remake(newRow); + setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), + mTable->data (mTable->index (newRow, 0)).toString().toStdString())); mRow = newRow; } @@ -410,6 +412,8 @@ void CSVWorld::DialogueSubView::nextId() } mEditWidget->remake(newRow); + setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), + mTable->data (mTable->index (newRow, 0)).toString().toStdString())); mRow = newRow; } From 1a9d4204d2a4750fc7dc9f944632dd36a2e622da Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 12 Mar 2014 15:07:17 +0100 Subject: [PATCH 035/127] correction --- apps/opencs/view/world/dialoguesubview.cpp | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index f8cb81a8ff..2a5dd93c67 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -377,11 +377,6 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM void CSVWorld::DialogueSubView::prevId() { - if (mRow < 1) - { - return; - } - int newRow = mRow - 1; QModelIndex newIndex(mTable->index(newRow, 0)); @@ -398,11 +393,6 @@ void CSVWorld::DialogueSubView::prevId() void CSVWorld::DialogueSubView::nextId() { - if (mRow == -1) - { - return; - } - int newRow = mRow + 1; QModelIndex newIndex(mTable->index(newRow, 0)); From 2278eb5e9104db721424dff6c5fb60622e362e57 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 12 Mar 2014 15:17:49 +0100 Subject: [PATCH 036/127] handle locking --- apps/opencs/view/world/dialoguesubview.cpp | 9 +++++++-- apps/opencs/view/world/dialoguesubview.hpp | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 2a5dd93c67..a8bd899c91 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -351,7 +351,8 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mMainLayout(NULL), mUndoStack(document.getUndoStack()), mTable(dynamic_cast(document.getData().getTableModel(id))), - mRow (-1) + mRow (-1), + mLocked(false) { mRow = mTable->getModelIndex (id.getId(), 0).row(); @@ -373,6 +374,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mEditWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); setWidget(mainWidget); + mEditWidget->setDisabled(mLocked); } void CSVWorld::DialogueSubView::prevId() @@ -389,6 +391,7 @@ void CSVWorld::DialogueSubView::prevId() setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), mTable->data (mTable->index (newRow, 0)).toString().toStdString())); mRow = newRow; + mEditWidget->setDisabled(mLocked); } void CSVWorld::DialogueSubView::nextId() @@ -405,9 +408,11 @@ void CSVWorld::DialogueSubView::nextId() setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), mTable->data (mTable->index (newRow, 0)).toString().toStdString())); mRow = newRow; + mEditWidget->setDisabled(mLocked); } void CSVWorld::DialogueSubView::setEditLock (bool locked) { - + mLocked = locked; + mEditWidget->setDisabled(mLocked); } \ No newline at end of file diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 0576c7aff7..b42b125559 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -145,6 +145,7 @@ namespace CSVWorld CSMWorld::IdTable* mTable; QUndoStack& mUndoStack; int mRow; + bool mLocked; public: From d1290ac5568704b15d3e85b711684ff40aa33d52 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 12 Mar 2014 15:46:27 +0100 Subject: [PATCH 037/127] skip deleled or erased records --- apps/opencs/view/world/dialoguesubview.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index a8bd899c91..97f116c06c 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -23,6 +23,7 @@ #include "../../model/world/columnbase.hpp" #include "../../model/world/idtable.hpp" #include "../../model/world/columns.hpp" +#include "../../model/world/record.hpp" #include "recordstatusdelegate.hpp" #include "util.hpp" @@ -387,6 +388,13 @@ void CSVWorld::DialogueSubView::prevId() return; } + CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (newRow, 1)).toInt()); + if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Deleted) + { + prevId(); + return; + } + mEditWidget->remake(newRow); setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), mTable->data (mTable->index (newRow, 0)).toString().toStdString())); @@ -404,6 +412,13 @@ void CSVWorld::DialogueSubView::nextId() return; } + CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (newRow, 1)).toInt()); + if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Deleted) + { + nextId(); + return; + } + mEditWidget->remake(newRow); setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), mTable->data (mTable->index (newRow, 0)).toString().toStdString())); From 919065db327b085383f19bb7bebba273fefd949b Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 12 Mar 2014 16:06:59 +0100 Subject: [PATCH 038/127] fixed segfault --- apps/opencs/view/world/dialoguesubview.cpp | 37 ++++++++++++++++++++-- apps/opencs/view/world/dialoguesubview.hpp | 3 ++ 2 files changed, 37 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 97f116c06c..bfb296a0e6 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -356,6 +356,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mLocked(false) { + connect(mTable, SIGNAL(dataChanged ( const QModelIndex &, const QModelIndex &)), this, SLOT(dataChanged())); mRow = mTable->getModelIndex (id.getId(), 0).row(); QWidget *mainWidget = new QWidget(this); @@ -375,12 +376,24 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mEditWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); setWidget(mainWidget); - mEditWidget->setDisabled(mLocked); + + CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (mRow, 1)).toInt()); + if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased) + { + mEditWidget->setDisabled(true); + } else + { + mEditWidget->setDisabled(mLocked); + } } void CSVWorld::DialogueSubView::prevId() { int newRow = mRow - 1; + if (newRow < 0) + { + return; + } QModelIndex newIndex(mTable->index(newRow, 0)); if (!newIndex.isValid()) @@ -389,7 +402,7 @@ void CSVWorld::DialogueSubView::prevId() } CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (newRow, 1)).toInt()); - if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Deleted) + if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased) { prevId(); return; @@ -405,6 +418,12 @@ void CSVWorld::DialogueSubView::prevId() void CSVWorld::DialogueSubView::nextId() { int newRow = mRow + 1; + + if (newRow > mTable->rowCount()) + { + return; + } + QModelIndex newIndex(mTable->index(newRow, 0)); if (!newIndex.isValid()) @@ -413,7 +432,7 @@ void CSVWorld::DialogueSubView::nextId() } CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (newRow, 1)).toInt()); - if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Deleted) + if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased) { nextId(); return; @@ -430,4 +449,16 @@ void CSVWorld::DialogueSubView::setEditLock (bool locked) { mLocked = locked; mEditWidget->setDisabled(mLocked); +} + +void CSVWorld::DialogueSubView::dataChanged() +{ + CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (mRow, 1)).toInt()); + if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased) + { + mEditWidget->setDisabled(true); + } else + { + mEditWidget->setDisabled(mLocked); + } } \ No newline at end of file diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index b42b125559..62d95b6222 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -158,6 +158,9 @@ namespace CSVWorld void nextId(); void prevId(); + + void dataChanged(); + ///\brief we need to care for deleting currently edited record }; } From 30a0c82e2212f2e44e496c8526f8effe5593f3a6 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 12 Mar 2014 16:28:10 +0100 Subject: [PATCH 039/127] this code segfaults, but i don't know why --- apps/opencs/view/world/dialoguesubview.cpp | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index bfb296a0e6..c041dd1f4d 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -377,14 +377,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM setWidget(mainWidget); - CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (mRow, 1)).toInt()); - if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased) - { - mEditWidget->setDisabled(true); - } else - { - mEditWidget->setDisabled(mLocked); - } + dataChanged(); } void CSVWorld::DialogueSubView::prevId() @@ -421,6 +414,7 @@ void CSVWorld::DialogueSubView::nextId() if (newRow > mTable->rowCount()) { + std::cout<<"test"< Date: Wed, 12 Mar 2014 19:36:46 +0100 Subject: [PATCH 040/127] added the new qlineedit subclass --- apps/opencs/view/world/table.cpp | 4 ++-- apps/opencs/view/world/util.cpp | 27 +++++++++++++++++++++++++-- apps/opencs/view/world/util.hpp | 25 +++++++++++++++++++++++++ 3 files changed, 52 insertions(+), 4 deletions(-) diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index 4bb9955e6e..f7f42eb5f1 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -528,7 +528,7 @@ void CSVWorld::Table::mouseMoveEvent (QMouseEvent* event) void CSVWorld::Table::dragEnterEvent(QDragEnterEvent *event) { - event->acceptProposedAction(); + event->acceptProposedAction(); } void CSVWorld::Table::dropEvent(QDropEvent *event) @@ -560,7 +560,7 @@ void CSVWorld::Table::dropEvent(QDropEvent *event) void CSVWorld::Table::dragMoveEvent(QDragMoveEvent *event) { - event->accept(); + event->accept(); } std::vector CSVWorld::Table::getColumnsWithDisplay(CSMWorld::ColumnBase::Display display) const diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index 85d8392ffe..cc9fac1cb3 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -12,9 +12,10 @@ #include #include #include +#include #include "../../model/world/commands.hpp" -#include +#include "../../model/world/tablemimedata.hpp" CSVWorld::NastyTableModelHack::NastyTableModelHack (QAbstractItemModel& model) : mModel (model) @@ -167,7 +168,7 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO display == CSMWorld::ColumnBase::Display_Class || display == CSMWorld::ColumnBase::Display_Faction) { - return new QLineEdit(parent); + return new DropLineEdit(parent); } if (display == CSMWorld::ColumnBase::Display_Boolean) { @@ -233,4 +234,26 @@ void CSVWorld::CommandDelegate::setEditorData (QWidget *editor, const QModelInde editor->setProperty(n, v); } +} + +CSVWorld::DropLineEdit::DropLineEdit(QWidget* parent) : +QLineEdit(parent) +{ + setAcceptDrops(true); +} + +void CSVWorld::DropLineEdit::dragEnterEvent(QDragEnterEvent *event) +{ + event->acceptProposedAction(); +} + +void CSVWorld::DropLineEdit::dragMoveEvent(QDragMoveEvent *event) +{ + event->accept(); +} + +void CSVWorld::DropLineEdit::dropEvent(QDropEvent *event) +{ + emit tableMimeDataDropped(dynamic_cast (event->mimeData())->getData()); + //WIP } \ No newline at end of file diff --git a/apps/opencs/view/world/util.hpp b/apps/opencs/view/world/util.hpp index 814f09d3a2..a70af9dc8a 100644 --- a/apps/opencs/view/world/util.hpp +++ b/apps/opencs/view/world/util.hpp @@ -5,11 +5,18 @@ #include #include +#include #include "../../model/world/columnbase.hpp" class QUndoStack; +namespace CSMWorld +{ + class TableMimeData; + class UniversalId; +} + namespace CSVWorld { ///< \brief Getting the data out of an editor widget @@ -79,6 +86,24 @@ namespace CSVWorld }; + class DropLineEdit : public QLineEdit + { + Q_OBJECT + + public: + DropLineEdit(QWidget *parent); + + private: + void dragEnterEvent(QDragEnterEvent *event); + + void dragMoveEvent(QDragMoveEvent *event); + + void dropEvent(QDropEvent *event); + + signals: + void tableMimeDataDropped(const std::vector& data); + }; + ///< \brief Use commands instead of manipulating the model directly class CommandDelegate : public QStyledItemDelegate { From fd4829141de2fe80112ac36776e56fae82e972db Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 12 Mar 2014 19:55:51 +0100 Subject: [PATCH 041/127] succesfully connected the signals --- apps/opencs/view/world/dialoguesubview.cpp | 7 ++++++- apps/opencs/view/world/dialoguesubview.hpp | 2 ++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index c041dd1f4d..a1c9de6125 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -113,6 +113,10 @@ QWidget* CSVWorld::DialogueDelegateDispatcherProxy::getEditor() const return mEditor; } +void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std::vector& data) +{ + std::cout<<"Test!"<(editor)) + if (qobject_cast(editor)) { connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); + connect(editor, SIGNAL(tableMimeDataDropped(const std::vector&)), proxy, SLOT(tableMimeDataDropped(const std::vector&))); skip = true; } if(!skip && qobject_cast(editor)) diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 62d95b6222..e133041b88 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -69,6 +69,7 @@ namespace CSVWorld CSMWorld::ColumnBase::Display mDisplay; std::auto_ptr mIndexWrapper; + public: DialogueDelegateDispatcherProxy(QWidget* editor, CSMWorld::ColumnBase::Display display); QWidget* getEditor() const; @@ -76,6 +77,7 @@ namespace CSVWorld public slots: void editorDataCommited(); void setIndex(const QModelIndex& index); + void tableMimeDataDropped(const std::vector& data); signals: void editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display); From cc1ceb35ce1c6173add9f738d8ea91434960b849 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 12 Mar 2014 20:34:55 +0100 Subject: [PATCH 042/127] drag and drop works --- apps/opencs/view/world/dialoguesubview.cpp | 20 +++++++++++++++++++- apps/opencs/view/world/dialoguesubview.hpp | 2 +- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index a1c9de6125..65e9c5cb32 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -24,6 +24,7 @@ #include "../../model/world/idtable.hpp" #include "../../model/world/columns.hpp" #include "../../model/world/record.hpp" +#include "../../model/world/tablemimedata.hpp" #include "recordstatusdelegate.hpp" #include "util.hpp" @@ -115,7 +116,19 @@ QWidget* CSVWorld::DialogueDelegateDispatcherProxy::getEditor() const void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std::vector& data) { - std::cout<<"Test!"<(mEditor); + if (lineEdit && mIndexWrapper.get()) + { + lineEdit->setText(data[i].getId().c_str()); + emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay); + break; + } + } + } } /* ==============================DialogueDelegateDispatcher========================================== @@ -242,6 +255,11 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: connect(editor, SIGNAL(currentIndexChanged (int)), proxy, SLOT(editorDataCommited())); skip = true; } + if(!skip && qobject_cast(editor)) + { + connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); + skip = true; + } connect(proxy, SIGNAL(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display)), this, SLOT(editorDataCommited(QWidget*, const QModelIndex&, CSMWorld::ColumnBase::Display))); mProxys.push_back(proxy); //deleted in the destructor diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index e133041b88..df985d5f8b 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -90,7 +90,7 @@ namespace CSVWorld QObject* mParent; - CSMWorld::IdTable* mTable; //nor sure if it is needed TODO + CSMWorld::IdTable* mTable; QUndoStack& mUndoStack; From dd755a00e47bbfe1631f9eaaf6422ff62b829938 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 13 Mar 2014 08:52:37 +0100 Subject: [PATCH 043/127] fix for the bug (?) --- apps/opencs/view/world/table.cpp | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index f7f42eb5f1..7f98801cb2 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -508,20 +508,7 @@ void CSVWorld::Table::mouseMoveEvent (QMouseEvent* event) drag->setMimeData (mime); drag->setPixmap (QString::fromStdString (mime->getIcon())); - - Qt::DropActions action = Qt::IgnoreAction; - switch (QApplication::keyboardModifiers()) - { - case Qt::ControlModifier: - action = Qt::CopyAction; - break; - - case Qt::ShiftModifier: - action = Qt::MoveAction; - break; - } - - drag->exec(action); + drag->exec(Qt::CopyAction); } } From e1a4b64efb7172cd30271c56b003870f2ec8c76a Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 13 Mar 2014 16:50:04 +0100 Subject: [PATCH 044/127] fixed segfault --- apps/opencs/model/world/tablemimedata.cpp | 5 + apps/opencs/model/world/tablemimedata.hpp | 2 + apps/opencs/view/world/dialoguesubview.cpp | 103 +++++++++++++-------- apps/opencs/view/world/dialoguesubview.hpp | 24 ++++- apps/opencs/view/world/util.cpp | 4 +- apps/opencs/view/world/util.hpp | 3 +- 6 files changed, 98 insertions(+), 43 deletions(-) diff --git a/apps/opencs/model/world/tablemimedata.cpp b/apps/opencs/model/world/tablemimedata.cpp index b56c9c8c25..9dcecf3bc1 100644 --- a/apps/opencs/model/world/tablemimedata.cpp +++ b/apps/opencs/model/world/tablemimedata.cpp @@ -443,4 +443,9 @@ CSMWorld::ColumnBase::Display CSMWorld::TableMimeData::convertEnums (CSMWorld::U default: return CSMWorld::ColumnBase::Display_None; } +} + +const CSMDoc::Document* CSMWorld::TableMimeData::getDocumentPtr() const +{ + return &mDocument; } \ No newline at end of file diff --git a/apps/opencs/model/world/tablemimedata.hpp b/apps/opencs/model/world/tablemimedata.hpp index 7687f3555f..44ac0f5f64 100644 --- a/apps/opencs/model/world/tablemimedata.hpp +++ b/apps/opencs/model/world/tablemimedata.hpp @@ -48,6 +48,8 @@ namespace CSMWorld UniversalId returnMatching(UniversalId::Type type) const; + const CSMDoc::Document* getDocumentPtr() const; + UniversalId returnMatching(CSMWorld::ColumnBase::Display type) const; static CSMWorld::UniversalId::Type convertEnums(CSMWorld::ColumnBase::Display type); diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 65e9c5cb32..50d19378d2 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -25,6 +25,7 @@ #include "../../model/world/columns.hpp" #include "../../model/world/record.hpp" #include "../../model/world/tablemimedata.hpp" +#include "../../model/doc/document.hpp" #include "recordstatusdelegate.hpp" #include "util.hpp" @@ -114,7 +115,7 @@ QWidget* CSVWorld::DialogueDelegateDispatcherProxy::getEditor() const return mEditor; } -void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std::vector& data) +void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std::vector& data, const CSMDoc::Document* document) { for (unsigned i = 0; i < data.size(); ++i) { @@ -123,8 +124,7 @@ void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std:: QLineEdit* lineEdit = qobject_cast(mEditor); if (lineEdit && mIndexWrapper.get()) { - lineEdit->setText(data[i].getId().c_str()); - emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay); + emit tableMimeDataDropped(mEditor, mIndexWrapper->mIndex, data[i], document); break; } } @@ -237,7 +237,10 @@ QWidget* CSVWorld::DialogueDelegateDispatcher::makeEditor(CSMWorld::ColumnBase:: if (qobject_cast(editor)) { connect(editor, SIGNAL(editingFinished()), proxy, SLOT(editorDataCommited())); - connect(editor, SIGNAL(tableMimeDataDropped(const std::vector&)), proxy, SLOT(tableMimeDataDropped(const std::vector&))); + connect(editor, SIGNAL(tableMimeDataDropped(const std::vector&, const CSMDoc::Document*)), + proxy, SLOT(tableMimeDataDropped(const std::vector&, const CSMDoc::Document*))); + connect(proxy, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), + this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); skip = true; } if(!skip && qobject_cast(editor)) @@ -288,6 +291,7 @@ mUndoStack(undoStack), mTable(table) { remake (row); + connect(&mDispatcher, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); } void CSVWorld::EditWidget::remake(int row) @@ -376,7 +380,8 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mUndoStack(document.getUndoStack()), mTable(dynamic_cast(document.getData().getTableModel(id))), mRow (-1), - mLocked(false) + mLocked(false), + mDocument(document) { connect(mTable, SIGNAL(dataChanged ( const QModelIndex &, const QModelIndex &)), this, SLOT(dataChanged())); @@ -394,6 +399,10 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mMainLayout = new QVBoxLayout(mainWidget); mEditWidget = new EditWidget(mainWidget, mRow, mTable, mUndoStack, false); + connect(mEditWidget, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), + this, SLOT(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); + + mMainLayout->addLayout(buttonsLayout); mMainLayout->addWidget(mEditWidget); mEditWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); @@ -410,56 +419,59 @@ void CSVWorld::DialogueSubView::prevId() { return; } - QModelIndex newIndex(mTable->index(newRow, 0)); - - if (!newIndex.isValid()) + while (newRow >= 0) { - return; - } + QModelIndex newIndex(mTable->index(newRow, 0)); - CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (newRow, 1)).toInt()); - if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased) - { - prevId(); - return; - } + if (!newIndex.isValid()) + { + return; + } - mEditWidget->remake(newRow); - setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), - mTable->data (mTable->index (newRow, 0)).toString().toStdString())); - mRow = newRow; - mEditWidget->setDisabled(mLocked); + CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (newRow, 1)).toInt()); + if (!(state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased)) + { + mEditWidget->remake(newRow); + setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), + mTable->data (mTable->index (newRow, 0)).toString().toStdString())); + mRow = newRow; + mEditWidget->setDisabled(mLocked); + return; + } + --newRow; + } } void CSVWorld::DialogueSubView::nextId() { int newRow = mRow + 1; - if (newRow > mTable->rowCount()) - { - std::cout<<"test"<index(newRow, 0)); - - if (!newIndex.isValid()) + if (newRow >= mTable->rowCount()) { return; } - CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (newRow, 1)).toInt()); - if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased) + while (newRow < mTable->rowCount()) { - nextId(); - return; - } + QModelIndex newIndex(mTable->index(newRow, 0)); - mEditWidget->remake(newRow); - setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), + if (!newIndex.isValid()) + { + return; + } + + CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (newRow, 1)).toInt()); + if (!(state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased)) + { + mEditWidget->remake(newRow); + setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), mTable->data (mTable->index (newRow, 0)).toString().toStdString())); - mRow = newRow; - mEditWidget->setDisabled(mLocked); + mRow = newRow; + mEditWidget->setDisabled(mLocked); + return; + } + ++newRow; + } } void CSVWorld::DialogueSubView::setEditLock (bool locked) @@ -478,4 +490,15 @@ void CSVWorld::DialogueSubView::dataChanged() { mEditWidget->setDisabled(mLocked); } -} \ No newline at end of file +} + +void CSVWorld::DialogueSubView::tableMimeDataDropped(QWidget* editor, + const QModelIndex& index, + const CSMWorld::UniversalId& id, + const CSMDoc::Document* document) +{ + if (document == &mDocument) + { + qobject_cast(editor)->setText(id.getId().c_str()); + } +} diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index df985d5f8b..1c8aa5971d 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -77,10 +77,15 @@ namespace CSVWorld public slots: void editorDataCommited(); void setIndex(const QModelIndex& index); - void tableMimeDataDropped(const std::vector& data); + void tableMimeDataDropped(const std::vector& data, const CSMDoc::Document* document); signals: void editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display); + + void tableMimeDataDropped(QWidget* editor, const QModelIndex& index, + const CSMWorld::UniversalId& id, + const CSMDoc::Document* document); + }; class DialogueDelegateDispatcher : public QAbstractItemDelegate @@ -121,10 +126,17 @@ namespace CSVWorld private slots: void editorDataCommited(QWidget* editor, const QModelIndex& index, CSMWorld::ColumnBase::Display display); + signals: + void tableMimeDataDropped(QWidget* editor, const QModelIndex& index, + const CSMWorld::UniversalId& id, + const CSMDoc::Document* document); + + }; class EditWidget : public QScrollArea { + Q_OBJECT QDataWidgetMapper *mWidgetMapper; DialogueDelegateDispatcher mDispatcher; QWidget* mMainWidget; @@ -136,6 +148,11 @@ namespace CSVWorld EditWidget (QWidget *parent, int row, CSMWorld::IdTable* table, QUndoStack& undoStack, bool createAndDelete = false); void remake(int row); + + signals: + void tableMimeDataDropped(QWidget* editor, const QModelIndex& index, + const CSMWorld::UniversalId& id, + const CSMDoc::Document* document); }; class DialogueSubView : public CSVDoc::SubView @@ -148,6 +165,7 @@ namespace CSVWorld QUndoStack& mUndoStack; int mRow; bool mLocked; + const CSMDoc::Document& mDocument; public: @@ -163,6 +181,10 @@ namespace CSVWorld void dataChanged(); ///\brief we need to care for deleting currently edited record + + void tableMimeDataDropped(QWidget* editor, const QModelIndex& index, + const CSMWorld::UniversalId& id, + const CSMDoc::Document* document); }; } diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index cc9fac1cb3..7278f34715 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -254,6 +254,8 @@ void CSVWorld::DropLineEdit::dragMoveEvent(QDragMoveEvent *event) void CSVWorld::DropLineEdit::dropEvent(QDropEvent *event) { - emit tableMimeDataDropped(dynamic_cast (event->mimeData())->getData()); + const CSMWorld::TableMimeData* data(dynamic_cast(event->mimeData())); + emit tableMimeDataDropped(data->getData(), data->getDocumentPtr()); + emit editingFinished (); //WIP } \ No newline at end of file diff --git a/apps/opencs/view/world/util.hpp b/apps/opencs/view/world/util.hpp index a70af9dc8a..7664f3eae2 100644 --- a/apps/opencs/view/world/util.hpp +++ b/apps/opencs/view/world/util.hpp @@ -8,6 +8,7 @@ #include #include "../../model/world/columnbase.hpp" +#include "../../model/doc/document.hpp" class QUndoStack; @@ -101,7 +102,7 @@ namespace CSVWorld void dropEvent(QDropEvent *event); signals: - void tableMimeDataDropped(const std::vector& data); + void tableMimeDataDropped(const std::vector& data, const CSMDoc::Document* document); }; ///< \brief Use commands instead of manipulating the model directly From c97172d89c66c411c2f3b550c6b5119e47f3654a Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 13 Mar 2014 17:00:14 +0100 Subject: [PATCH 045/127] fixed segfault and prevent drops from other documents --- apps/opencs/view/world/dialoguesubview.cpp | 1 + apps/opencs/view/world/util.cpp | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 50d19378d2..fdef57c41b 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -125,6 +125,7 @@ void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std:: if (lineEdit && mIndexWrapper.get()) { emit tableMimeDataDropped(mEditor, mIndexWrapper->mIndex, data[i], document); + emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay); break; } } diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index 7278f34715..a71937b085 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -256,6 +256,5 @@ void CSVWorld::DropLineEdit::dropEvent(QDropEvent *event) { const CSMWorld::TableMimeData* data(dynamic_cast(event->mimeData())); emit tableMimeDataDropped(data->getData(), data->getDocumentPtr()); - emit editingFinished (); //WIP } \ No newline at end of file From 4a623ace7159589e8ea1b1180d95305f86e9f5ce Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 13 Mar 2014 18:26:59 +0100 Subject: [PATCH 046/127] disabling works --- apps/opencs/view/world/dialoguesubview.cpp | 28 ++++++++++++++-------- apps/opencs/view/world/dialoguesubview.hpp | 2 +- 2 files changed, 19 insertions(+), 11 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index fdef57c41b..17b665d46f 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -363,7 +363,7 @@ void CSVWorld::EditWidget::remake(int row) mWidgetMapper->setCurrentModelIndex(mTable->index(row, 0)); - this->setMinimumWidth(300); + this->setMinimumWidth(325); //TODO find better way to set the width this->setWidget(mMainWidget); this->setWidgetResizable(true); } @@ -385,7 +385,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mDocument(document) { - connect(mTable, SIGNAL(dataChanged ( const QModelIndex &, const QModelIndex &)), this, SLOT(dataChanged())); + connect(mTable, SIGNAL(dataChanged (const QModelIndex&, const QModelIndex&)), this, SLOT(dataChanged(const QModelIndex&))); mRow = mTable->getModelIndex (id.getId(), 0).row(); QWidget *mainWidget = new QWidget(this); @@ -403,14 +403,12 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM connect(mEditWidget, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SLOT(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); - mMainLayout->addLayout(buttonsLayout); mMainLayout->addWidget(mEditWidget); mEditWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + dataChanged(mTable->index(mRow, 0)); setWidget(mainWidget); - - dataChanged(); } void CSVWorld::DialogueSubView::prevId() @@ -478,11 +476,6 @@ void CSVWorld::DialogueSubView::nextId() void CSVWorld::DialogueSubView::setEditLock (bool locked) { mLocked = locked; - mEditWidget->setDisabled(mLocked); -} - -void CSVWorld::DialogueSubView::dataChanged() -{ CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (mRow, 1)).toInt()); if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased) { @@ -493,6 +486,21 @@ void CSVWorld::DialogueSubView::dataChanged() } } +void CSVWorld::DialogueSubView::dataChanged(const QModelIndex & index) +{ + if (index.row() == mRow) + { + CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (mRow, 1)).toInt()); + if (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased) + { + mEditWidget->setDisabled(true); + } else + { + mEditWidget->setDisabled(mLocked); + } + } +} + void CSVWorld::DialogueSubView::tableMimeDataDropped(QWidget* editor, const QModelIndex& index, const CSMWorld::UniversalId& id, diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 1c8aa5971d..c2e7da3382 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -179,7 +179,7 @@ namespace CSVWorld void prevId(); - void dataChanged(); + void dataChanged(const QModelIndex & index); ///\brief we need to care for deleting currently edited record void tableMimeDataDropped(QWidget* editor, const QModelIndex& index, From c36dfef972b858d0b640f0bb0f1f0604c685dce2 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 16 Mar 2014 12:44:01 +0100 Subject: [PATCH 047/127] prewview subview --- apps/opencs/CMakeLists.txt | 8 +++- apps/opencs/editor.cpp | 47 +++++++++++++++++++-- apps/opencs/editor.hpp | 8 ++++ apps/opencs/main.cpp | 6 +++ apps/opencs/view/render/previewwidget.cpp | 45 ++++++++++++++++++++ apps/opencs/view/render/previewwidget.hpp | 42 +++++++++++++++++++ apps/opencs/view/world/previewsubview.cpp | 50 +++++++++++++++++++++++ apps/opencs/view/world/previewsubview.hpp | 36 ++++++++++++++++ apps/opencs/view/world/subviews.cpp | 3 ++ 9 files changed, 240 insertions(+), 5 deletions(-) create mode 100644 apps/opencs/view/render/previewwidget.cpp create mode 100644 apps/opencs/view/render/previewwidget.hpp create mode 100644 apps/opencs/view/world/previewsubview.cpp create mode 100644 apps/opencs/view/world/previewsubview.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 621b9bf869..7cdaad5bea 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -60,11 +60,12 @@ opencs_hdrs_noqt (view/doc opencs_units (view/world table tablesubview scriptsubview util regionmapsubview tablebottombox creator genericcreator cellcreator referenceablecreator referencecreator scenesubview scenetoolbar scenetool - scenetoolmode infocreator scriptedit + scenetoolmode infocreator scriptedit previewsubview ) opencs_units (view/render scenewidget worldspacewidget pagedworldspacewidget unpagedworldspacewidget + previewwidget ) opencs_units_noqt (view/render @@ -147,6 +148,9 @@ if(WIN32) set(QT_USE_QTMAIN TRUE) endif(WIN32) +set(BOOST_COMPONENTS system filesystem program_options thread wave) +find_package(Boost REQUIRED COMPONENTS ${BOOST_COMPONENTS}) + find_package(Qt4 COMPONENTS QtCore QtGui QtNetwork REQUIRED) include(${QT_USE_FILE}) @@ -187,6 +191,8 @@ if(APPLE) endif(APPLE) target_link_libraries(opencs + ${OGRE_LIBRARIES} + ${SHINY_LIBRARIES} ${Boost_LIBRARIES} ${QT_LIBRARIES} components diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 9eb95fafac..942780c32b 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -9,6 +9,9 @@ #include #include +#include +#include + #include #include @@ -81,7 +84,7 @@ std::pair > CS::Editor::readConfi mCfgMgr.readConfiguration(variables, desc); - mDocumentManager.setResourceDir (variables["resources"].as()); + mDocumentManager.setResourceDir (mResources = variables["resources"].as()); mFsStrict = variables["fs-strict"].as(); @@ -225,6 +228,15 @@ int CS::Editor::run() if (mLocal.empty()) return 1; + mStartup.show(); + + QApplication::setQuitOnLastWindowClosed (true); + + return QApplication::exec(); +} + +std::auto_ptr CS::Editor::setupGraphics() +{ // TODO: setting Ogre::Root::getSingleton().setRenderSystem(Ogre::Root::getSingleton().getRenderSystemByName("OpenGL Rendering Subsystem")); @@ -242,9 +254,36 @@ int CS::Editor::run() Ogre::RenderWindow* hiddenWindow = Ogre::Root::getSingleton().createRenderWindow("InactiveHidden", 1, 1, false, ¶ms); hiddenWindow->setActive(false); - mStartup.show(); + sh::OgrePlatform* platform = + new sh::OgrePlatform ("General", (mResources / "materials").string()); - QApplication::setQuitOnLastWindowClosed (true); + if (!boost::filesystem::exists (mCfgMgr.getCachePath())) + boost::filesystem::create_directories (mCfgMgr.getCachePath()); - return QApplication::exec(); + platform->setCacheFolder (mCfgMgr.getCachePath().string()); + + std::auto_ptr factory (new sh::Factory (platform)); + + factory->setCurrentLanguage (sh::Language_GLSL); /// \todo make this configurable + factory->setWriteSourceCache (true); + factory->setReadSourceCache (true); + factory->setReadMicrocodeCache (true); + factory->setWriteMicrocodeCache (true); + + factory->loadAllFiles(); + + sh::Factory::getInstance().setGlobalSetting ("fog", "true"); + + sh::Factory::getInstance().setGlobalSetting ("shadows", "false"); + sh::Factory::getInstance().setGlobalSetting ("shadows_pssm", "false"); + + sh::Factory::getInstance ().setGlobalSetting ("render_refraction", "false"); + + sh::Factory::getInstance ().setGlobalSetting ("viewproj_fix", "false"); + + sh::Factory::getInstance ().setGlobalSetting ("num_lights", "8"); + + /// \todo add more configurable shiny settings + + return factory; } diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index ec417ba8e0..164398fb73 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -1,11 +1,15 @@ #ifndef CS_EDITOR_H #define CS_EDITOR_H +#include + #include #include #include #include +#include + #ifndef Q_MOC_RUN #include #endif @@ -42,6 +46,7 @@ namespace CS CSVSettings::UserSettingsDialog mSettings; CSVDoc::FileDialog mFileDialog; boost::filesystem::path mLocal; + boost::filesystem::path mResources; bool mFsStrict; void setupDataFiles (const Files::PathContainer& dataDirs); @@ -63,6 +68,9 @@ namespace CS int run(); ///< \return error status + std::auto_ptr setupGraphics(); + ///< The returned factory must persist at least as long as *this. + private slots: void createGame(); diff --git a/apps/opencs/main.cpp b/apps/opencs/main.cpp index 212ed08367..eded36394a 100644 --- a/apps/opencs/main.cpp +++ b/apps/opencs/main.cpp @@ -7,6 +7,8 @@ #include #include +#include + #include #ifdef Q_OS_MAC @@ -42,6 +44,8 @@ int main(int argc, char *argv[]) OgreInit::OgreInit ogreInit; + std::auto_ptr shinyFactory; + Application application (argc, argv); #ifdef Q_OS_MAC @@ -73,5 +77,7 @@ int main(int argc, char *argv[]) // return 0; } + shinyFactory = editor.setupGraphics(); + return editor.run(); } diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp new file mode 100644 index 0000000000..160240b172 --- /dev/null +++ b/apps/opencs/view/render/previewwidget.cpp @@ -0,0 +1,45 @@ + +#include "previewwidget.hpp" + +#include + +#include "../../model/world/data.hpp" + +void CSVRender::PreviewWidget::setup (const std::string& id) +{ + setNavigation (&mOrbit); + + int column = mData.getReferenceables().findColumnIndex (CSMWorld::Columns::ColumnId_Model); + + int row = mData.getReferenceables().getIndex (id); + + QVariant value = mData.getReferenceables().getData (row, column); + + if (!value.isValid()) + return; + + std::string model = value.toString().toUtf8().constData(); + + if (model.empty()) + return; + + Ogre::SceneNode* node = getSceneManager()->getRootSceneNode()->createChildSceneNode(); + node->setPosition (Ogre::Vector3 (0, 0, 0)); + + mObject = NifOgre::Loader::createObjects (node, "Meshes\\" + model); +} + +CSVRender::PreviewWidget::PreviewWidget (const CSMWorld::Data& data, + const std::string& referenceableId, QWidget *parent) +: SceneWidget (parent), mData (data) +{ + setup (referenceableId); +} + +CSVRender::PreviewWidget::PreviewWidget (const CSMWorld::Data& data, + const std::string& referenceableId, const std::string& referenceId, QWidget *parent) +: SceneWidget (parent), mData (data) +{ + setup (referenceableId); + /// \todo apply reference modifications (scale, rotation) +} diff --git a/apps/opencs/view/render/previewwidget.hpp b/apps/opencs/view/render/previewwidget.hpp new file mode 100644 index 0000000000..01d40050fb --- /dev/null +++ b/apps/opencs/view/render/previewwidget.hpp @@ -0,0 +1,42 @@ +#ifndef OPENCS_VIEW_PREVIEWWIDGET_H +#define OPENCS_VIEW_PREVIEWWIDGET_H + +#include + +#include "scenewidget.hpp" + +#include "navigationorbit.hpp" + +namespace CSMWorld +{ + class Data; +} + +namespace CSVRender +{ + class PreviewWidget : public SceneWidget + { + Q_OBJECT + + const CSMWorld::Data& mData; + CSVRender::NavigationOrbit mOrbit; + NifOgre::ObjectScenePtr mObject; + + void setup (const std::string& id); + ///< \param id ID of the referenceable to be viewed + + public: + + PreviewWidget (const CSMWorld::Data& data, const std::string& referenceableId, + QWidget *parent = 0); + + PreviewWidget (const CSMWorld::Data& data, const std::string& referenceableId, + const std::string& referenceId, QWidget *parent = 0); + + signals: + + void closeRequest(); + }; +} + +#endif diff --git a/apps/opencs/view/world/previewsubview.cpp b/apps/opencs/view/world/previewsubview.cpp new file mode 100644 index 0000000000..0fa1d3b174 --- /dev/null +++ b/apps/opencs/view/world/previewsubview.cpp @@ -0,0 +1,50 @@ + +#include "previewsubview.hpp" + +#include + +#include "../render/scenewidget.hpp" + +#include "scenetoolbar.hpp" + +#include "../render/previewwidget.hpp" + +CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) +: SubView (id) +{ + QHBoxLayout *layout = new QHBoxLayout; + + layout->setContentsMargins (QMargins (0, 0, 0, 0)); + + if (document.getData().getReferenceables().searchId (id.getId())==-1) + { + std::string referenceableId = + document.getData().getReferences().getRecord (id.getId()).get().mRefID; + + mScene = + new CSVRender::PreviewWidget (document.getData(), referenceableId, id.getId(), this); + } + else + mScene = new CSVRender::PreviewWidget (document.getData(), id.getId(), this); + + SceneToolbar *toolbar = new SceneToolbar (48, this); + + layout->addWidget (toolbar, 0); + + layout->addWidget (mScene, 1); + + QWidget *widget = new QWidget; + + widget->setLayout (layout); + + setWidget (widget); + + connect (mScene, SIGNAL (closeRequest()), this, SLOT (closeRequest())); +} + +void CSVWorld::PreviewSubView::setEditLock (bool locked) {} + +void CSVWorld::PreviewSubView::closeRequest() +{ + deleteLater(); +} \ No newline at end of file diff --git a/apps/opencs/view/world/previewsubview.hpp b/apps/opencs/view/world/previewsubview.hpp new file mode 100644 index 0000000000..e7a2a261ed --- /dev/null +++ b/apps/opencs/view/world/previewsubview.hpp @@ -0,0 +1,36 @@ +#ifndef CSV_WORLD_PREVIEWSUBVIEW_H +#define CSV_WORLD_PREVIEWSUBVIEW_H + +#include "../doc/subview.hpp" + +namespace CSMDoc +{ + class Document; +} + +namespace CSVRender +{ + class PreviewWidget; +} + +namespace CSVWorld +{ + class PreviewSubView : public CSVDoc::SubView + { + Q_OBJECT + + CSVRender::PreviewWidget *mScene; + + public: + + PreviewSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document); + + virtual void setEditLock (bool locked); + + private slots: + + void closeRequest(); + }; +} + +#endif diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 74ce03cce6..33a91330df 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -16,6 +16,7 @@ #include "scenesubview.hpp" #include "dialoguecreator.hpp" #include "infocreator.hpp" +#include "previewsubview.hpp" void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) { @@ -78,4 +79,6 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) CreatorFactory >); manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory); + + manager.add (CSMWorld::UniversalId::Type_Preview, new CSVDoc::SubViewFactory); } \ No newline at end of file From fa042a8aca3ca1ed8e11506763f8c6fd5987995f Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 16 Mar 2014 13:22:32 +0100 Subject: [PATCH 048/127] use proper title for reference prewview subviews (avoid internal ID) --- apps/opencs/view/render/previewwidget.hpp | 2 +- apps/opencs/view/world/previewsubview.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/render/previewwidget.hpp b/apps/opencs/view/render/previewwidget.hpp index 01d40050fb..c8834775b5 100644 --- a/apps/opencs/view/render/previewwidget.hpp +++ b/apps/opencs/view/render/previewwidget.hpp @@ -20,7 +20,7 @@ namespace CSVRender const CSMWorld::Data& mData; CSVRender::NavigationOrbit mOrbit; - NifOgre::ObjectScenePtr mObject; + NifOgre::ObjectScenePtr mObject; void setup (const std::string& id); ///< \param id ID of the referenceable to be viewed diff --git a/apps/opencs/view/world/previewsubview.cpp b/apps/opencs/view/world/previewsubview.cpp index 0fa1d3b174..587af561fb 100644 --- a/apps/opencs/view/world/previewsubview.cpp +++ b/apps/opencs/view/world/previewsubview.cpp @@ -21,6 +21,8 @@ CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDo std::string referenceableId = document.getData().getReferences().getRecord (id.getId()).get().mRefID; + setWindowTitle (("Preview: Reference to " + referenceableId).c_str()); + mScene = new CSVRender::PreviewWidget (document.getData(), referenceableId, id.getId(), this); } From b0a1e1198af8ba7bb526f61ac6c5eeef00dfe9de Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 16 Mar 2014 16:30:17 +0100 Subject: [PATCH 049/127] Yet another terrain fix --- components/terrain/quadtreenode.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/components/terrain/quadtreenode.cpp b/components/terrain/quadtreenode.cpp index 21c1becb0a..a14fe1f842 100644 --- a/components/terrain/quadtreenode.cpp +++ b/components/terrain/quadtreenode.cpp @@ -282,9 +282,6 @@ bool QuadTreeNode::update(const Ogre::Vector3 &cameraPos) size_t wantedLod = 0; float cellWorldSize = mTerrain->getStorage()->getCellWorldSize(); - if (!mTerrain->getDistantLandEnabled() && dist > cellWorldSize) - return true; - if (dist > cellWorldSize*64) wantedLod = 6; else if (dist > cellWorldSize*32) @@ -392,6 +389,8 @@ void QuadTreeNode::load(const LoadResponseData &data) mChunk = new Chunk(mTerrain->getBufferCache().getUVBuffer(), mBounds, data); mChunk->setVisibilityFlags(mTerrain->getVisiblityFlags()); mChunk->setCastShadows(true); + if (!mTerrain->getDistantLandEnabled()) + mChunk->setRenderingDistance(8192); mSceneNode->attachObject(mChunk); mMaterialGenerator->enableShadows(mTerrain->getShadowsEnabled()); From 4a0d1ba2729f6b7a4ffbbc289ea48f01f8172899 Mon Sep 17 00:00:00 2001 From: sirherrbatka Date: Sun, 16 Mar 2014 17:06:11 +0100 Subject: [PATCH 050/127] do not cast and check multiple times --- apps/opencs/view/world/dialoguesubview.cpp | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 17b665d46f..f0a4ac131e 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -117,17 +117,20 @@ QWidget* CSVWorld::DialogueDelegateDispatcherProxy::getEditor() const void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std::vector& data, const CSMDoc::Document* document) { + QLineEdit* lineEdit = qobject_cast(mEditor); + { + if (!lineEdit or !mIndexWrapper.get()) + { + return; + } + } for (unsigned i = 0; i < data.size(); ++i) { if (mDisplay == CSMWorld::TableMimeData::convertEnums(data[i].getType())) { - QLineEdit* lineEdit = qobject_cast(mEditor); - if (lineEdit && mIndexWrapper.get()) - { - emit tableMimeDataDropped(mEditor, mIndexWrapper->mIndex, data[i], document); - emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay); - break; - } + emit tableMimeDataDropped(mEditor, mIndexWrapper->mIndex, data[i], document); + emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay); + break; } } } From 48ea93d8907e2a7ba22cd555e6f35bfdf0ffef4d Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 16 Mar 2014 17:06:30 +0100 Subject: [PATCH 051/127] less random camera start position --- apps/opencs/view/render/scenewidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 7b790fd581..5a2d93385c 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -45,7 +45,7 @@ namespace CSVRender mCamera = mSceneMgr->createCamera("foo"); - mCamera->setPosition(300,300,300); + mCamera->setPosition(300,0,000); mCamera->lookAt(0,0,0); mCamera->setNearClipDistance(0.1); mCamera->setFarClipDistance(3000); From 6b11265fbc0b4d78dcd89554a2af3472bb0fb9d4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 16 Mar 2014 17:06:45 +0100 Subject: [PATCH 052/127] consider scale and orientation when previewing reference --- apps/opencs/view/render/previewwidget.cpp | 37 ++++++++++++++++++++--- apps/opencs/view/render/previewwidget.hpp | 4 +++ 2 files changed, 36 insertions(+), 5 deletions(-) diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp index 160240b172..43d45f4cb9 100644 --- a/apps/opencs/view/render/previewwidget.cpp +++ b/apps/opencs/view/render/previewwidget.cpp @@ -23,15 +23,42 @@ void CSVRender::PreviewWidget::setup (const std::string& id) if (model.empty()) return; - Ogre::SceneNode* node = getSceneManager()->getRootSceneNode()->createChildSceneNode(); - node->setPosition (Ogre::Vector3 (0, 0, 0)); + mNode = getSceneManager()->getRootSceneNode()->createChildSceneNode(); + mNode->setPosition (Ogre::Vector3 (0, 0, 0)); - mObject = NifOgre::Loader::createObjects (node, "Meshes\\" + model); + mObject = NifOgre::Loader::createObjects (mNode, "Meshes\\" + model); +} + +void CSVRender::PreviewWidget::adjust (const std::string& id) +{ + if (mNode) + { + int row = mData.getReferences().getIndex (id); + + float scale = mData.getReferences().getData (row, mData.getReferences(). + findColumnIndex (CSMWorld::Columns::ColumnId_Scale)).toFloat(); + float rotX = mData.getReferences().getData (row, mData.getReferences(). + findColumnIndex (CSMWorld::Columns::ColumnId_PositionXRot)).toFloat(); + float rotY = mData.getReferences().getData (row, mData.getReferences(). + findColumnIndex (CSMWorld::Columns::ColumnId_PositionYRot)).toFloat(); + float rotZ = mData.getReferences().getData (row, mData.getReferences(). + findColumnIndex (CSMWorld::Columns::ColumnId_PositionZRot)).toFloat(); + + mNode->setScale (scale, scale, scale); + + Ogre::Quaternion xr (Ogre::Radian(-rotX), Ogre::Vector3::UNIT_X); + + Ogre::Quaternion yr (Ogre::Radian(-rotY), Ogre::Vector3::UNIT_Y); + + Ogre::Quaternion zr (Ogre::Radian(-rotZ), Ogre::Vector3::UNIT_Z); + + mNode->setOrientation (xr*yr*zr); + } } CSVRender::PreviewWidget::PreviewWidget (const CSMWorld::Data& data, const std::string& referenceableId, QWidget *parent) -: SceneWidget (parent), mData (data) +: SceneWidget (parent), mData (data), mNode (0) { setup (referenceableId); } @@ -41,5 +68,5 @@ CSVRender::PreviewWidget::PreviewWidget (const CSMWorld::Data& data, : SceneWidget (parent), mData (data) { setup (referenceableId); - /// \todo apply reference modifications (scale, rotation) + adjust (referenceId); } diff --git a/apps/opencs/view/render/previewwidget.hpp b/apps/opencs/view/render/previewwidget.hpp index c8834775b5..b3abd55879 100644 --- a/apps/opencs/view/render/previewwidget.hpp +++ b/apps/opencs/view/render/previewwidget.hpp @@ -21,10 +21,14 @@ namespace CSVRender const CSMWorld::Data& mData; CSVRender::NavigationOrbit mOrbit; NifOgre::ObjectScenePtr mObject; + Ogre::SceneNode *mNode; void setup (const std::string& id); ///< \param id ID of the referenceable to be viewed + void adjust (const std::string& id); + ///< \param id ID of the reference to be viewed + public: PreviewWidget (const CSMWorld::Data& data, const std::string& referenceableId, From 3c8eeb8c48caf472d6c0d25c8b5de0165dcc9bbc Mon Sep 17 00:00:00 2001 From: sirherrbatka Date: Sun, 16 Mar 2014 17:11:13 +0100 Subject: [PATCH 053/127] added comment --- apps/opencs/view/world/dialoguesubview.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index f0a4ac131e..2e77cf29e0 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -306,6 +306,7 @@ void CSVWorld::EditWidget::remake(int row) } mMainWidget = new QWidget (this); + //not sure if widget mapper can handle deleting the widgets that were mapped if (mWidgetMapper) { delete mWidgetMapper; From 20ea859aac470906a1410fbf0602e9a52fc2c656 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 16 Mar 2014 17:14:44 +0100 Subject: [PATCH 054/127] adjusted the far clip distance --- apps/opencs/view/render/scenewidget.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 5a2d93385c..5eec702d3d 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -48,7 +48,7 @@ namespace CSVRender mCamera->setPosition(300,0,000); mCamera->lookAt(0,0,0); mCamera->setNearClipDistance(0.1); - mCamera->setFarClipDistance(3000); + mCamera->setFarClipDistance(30000); QTimer *timer = new QTimer (this); From 81dfc26d269587edf6be080acbf803db0b9cbdaf Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 16 Mar 2014 21:39:46 +0100 Subject: [PATCH 055/127] mwscript/locals was added twice --- apps/openmw/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 5e108edaf7..20011b0d99 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -44,7 +44,7 @@ add_openmw_dir (mwscript locals scriptmanagerimp compilercontext interpretercontext cellextensions miscextensions guiextensions soundextensions skyextensions statsextensions containerextensions aiextensions controlextensions extensions globalscripts ref dialogueextensions - animationextensions transformationextensions consoleextensions userextensions locals + animationextensions transformationextensions consoleextensions userextensions ) add_openmw_dir (mwsound From 49ef976b3dcaaf1e86639b1730fe8cb7f400b377 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 16 Mar 2014 23:30:45 +0100 Subject: [PATCH 056/127] Remove reference to no longer used font --- OFL.txt | 93 ------------------------------------------------------ readme.txt | 1 - 2 files changed, 94 deletions(-) delete mode 100644 OFL.txt diff --git a/OFL.txt b/OFL.txt deleted file mode 100644 index 043e85e83b..0000000000 --- a/OFL.txt +++ /dev/null @@ -1,93 +0,0 @@ -Copyright (c) 2010, 2011 Georg Duffner (http://www.georgduffner.at) - -This Font Software is licensed under the SIL Open Font License, Version 1.1. -This license is copied below, and is also available with a FAQ at: -http://scripts.sil.org/OFL - - ------------------------------------------------------------ -SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 ------------------------------------------------------------ - -PREAMBLE -The goals of the Open Font License (OFL) are to stimulate worldwide -development of collaborative font projects, to support the font creation -efforts of academic and linguistic communities, and to provide a free and -open framework in which fonts may be shared and improved in partnership -with others. - -The OFL allows the licensed fonts to be used, studied, modified and -redistributed freely as long as they are not sold by themselves. The -fonts, including any derivative works, can be bundled, embedded, -redistributed and/or sold with any software provided that any reserved -names are not used by derivative works. The fonts and derivatives, -however, cannot be released under any other type of license. The -requirement for fonts to remain under this license does not apply -to any document created using the fonts or their derivatives. - -DEFINITIONS -"Font Software" refers to the set of files released by the Copyright -Holder(s) under this license and clearly marked as such. This may -include source files, build scripts and documentation. - -"Reserved Font Name" refers to any names specified as such after the -copyright statement(s). - -"Original Version" refers to the collection of Font Software components as -distributed by the Copyright Holder(s). - -"Modified Version" refers to any derivative made by adding to, deleting, -or substituting -- in part or in whole -- any of the components of the -Original Version, by changing formats or by porting the Font Software to a -new environment. - -"Author" refers to any designer, engineer, programmer, technical -writer or other person who contributed to the Font Software. - -PERMISSION & CONDITIONS -Permission is hereby granted, free of charge, to any person obtaining -a copy of the Font Software, to use, study, copy, merge, embed, modify, -redistribute, and sell modified and unmodified copies of the Font -Software, subject to the following conditions: - -1) Neither the Font Software nor any of its individual components, -in Original or Modified Versions, may be sold by itself. - -2) Original or Modified Versions of the Font Software may be bundled, -redistributed and/or sold with any software, provided that each copy -contains the above copyright notice and this license. These can be -included either as stand-alone text files, human-readable headers or -in the appropriate machine-readable metadata fields within text or -binary files as long as those fields can be easily viewed by the user. - -3) No Modified Version of the Font Software may use the Reserved Font -Name(s) unless explicit written permission is granted by the corresponding -Copyright Holder. This restriction only applies to the primary font name as -presented to the users. - -4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font -Software shall not be used to promote, endorse or advertise any -Modified Version, except to acknowledge the contribution(s) of the -Copyright Holder(s) and the Author(s) or with their explicit written -permission. - -5) The Font Software, modified or unmodified, in part or in whole, -must be distributed entirely under this license, and must not be -distributed under any other license. The requirement for fonts to -remain under this license does not apply to any document created -using the Font Software. - -TERMINATION -This license becomes null and void if any of the above conditions are -not met. - -DISCLAIMER -THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF -MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT -OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE -COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL -DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM -OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/readme.txt b/readme.txt index bb17a68e70..a054626ddb 100644 --- a/readme.txt +++ b/readme.txt @@ -8,7 +8,6 @@ License: GPL (see GPL3.txt for more information) Website: http://www.openmw.org Font Licenses: -EBGaramond-Regular.ttf: OFL (see OFL.txt for more information) DejaVuLGCSansMono.ttf: custom (see DejaVu Font License.txt for more information) From c8c0e5de3870202d0b2be92c330d1e3289d6f249 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 16 Mar 2014 23:38:51 +0100 Subject: [PATCH 057/127] Fixed code issues found with unity build. Missing include guards, duplicated functions, ... --- apps/openmw/mwclass/container.cpp | 14 +++++----- apps/openmw/mwclass/creature.cpp | 22 +++++++-------- apps/openmw/mwclass/creaturelevlist.cpp | 8 +++--- apps/openmw/mwclass/light.cpp | 16 +++++------ apps/openmw/mwclass/npc.cpp | 28 ++++++++++---------- apps/openmw/mwgui/alchemywindow.cpp | 12 +-------- apps/openmw/mwgui/container.cpp | 15 +---------- apps/openmw/mwgui/dialogue.cpp | 13 +-------- apps/openmw/mwgui/hud.hpp | 5 ++++ apps/openmw/mwgui/itemselection.hpp | 5 ++++ apps/openmw/mwgui/itemview.cpp | 24 +++++++---------- apps/openmw/mwgui/itemview.hpp | 2 ++ apps/openmw/mwgui/journalbooks.cpp | 9 ------- apps/openmw/mwgui/journalbooks.hpp | 9 +++++++ apps/openmw/mwgui/mainmenu.hpp | 5 ++++ apps/openmw/mwgui/quickkeysmenu.cpp | 22 --------------- apps/openmw/mwgui/spellwindow.cpp | 22 --------------- apps/openmw/mwgui/spellwindow.hpp | 19 +++++++++++++ apps/openmw/mwmechanics/aiactivate.cpp | 14 ++-------- apps/openmw/mwmechanics/aiescort.cpp | 14 ++-------- apps/openmw/mwmechanics/aitravel.cpp | 14 ++-------- apps/openmw/mwmechanics/aiwander.cpp | 10 ------- apps/openmw/mwmechanics/pathfinding.cpp | 7 ----- apps/openmw/mwmechanics/pathfinding.hpp | 16 +++++++++++ apps/openmw/mwscript/containerextensions.cpp | 8 +++--- apps/openmw/mwscript/globalscripts.cpp | 8 +++--- apps/openmw/mwscript/guiextensions.cpp | 4 +-- apps/openmw/mwscript/statsextensions.cpp | 20 +++++++------- apps/openmw/mwsound/ffmpeg_decoder.cpp | 7 ++--- apps/openmw/mwsound/ffmpeg_decoder.hpp | 2 ++ components/bsa/bsa_file.cpp | 2 +- components/compiler/declarationparser.cpp | 4 +-- components/interpreter/runtime.cpp | 2 +- 33 files changed, 154 insertions(+), 228 deletions(-) diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index 715784b7cf..604b51990a 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -28,16 +28,16 @@ namespace { - struct CustomData : public MWWorld::CustomData + struct ContainerCustomData : public MWWorld::CustomData { MWWorld::ContainerStore mContainerStore; virtual MWWorld::CustomData *clone() const; }; - MWWorld::CustomData *CustomData::clone() const + MWWorld::CustomData *ContainerCustomData::clone() const { - return new CustomData (*this); + return new ContainerCustomData (*this); } } @@ -47,7 +47,7 @@ namespace MWClass { if (!ptr.getRefData().getCustomData()) { - std::auto_ptr data (new CustomData); + std::auto_ptr data (new ContainerCustomData); MWWorld::LiveCellRef *ref = ptr.get(); @@ -174,7 +174,7 @@ namespace MWClass { ensureCustomData (ptr); - return dynamic_cast (*ptr.getRefData().getCustomData()).mContainerStore; + return dynamic_cast (*ptr.getRefData().getCustomData()).mContainerStore; } std::string Container::getScript (const MWWorld::Ptr& ptr) const @@ -267,7 +267,7 @@ namespace MWClass ensureCustomData (ptr); - dynamic_cast (*ptr.getRefData().getCustomData()).mContainerStore. + dynamic_cast (*ptr.getRefData().getCustomData()).mContainerStore. readState (state2.mInventory); } @@ -278,7 +278,7 @@ namespace MWClass ensureCustomData (ptr); - dynamic_cast (*ptr.getRefData().getCustomData()).mContainerStore. + dynamic_cast (*ptr.getRefData().getCustomData()).mContainerStore. writeState (state2.mInventory); } } diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index c66bda09fa..0f7ffdc480 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -37,7 +37,7 @@ namespace { - struct CustomData : public MWWorld::CustomData + struct CreatureCustomData : public MWWorld::CustomData { MWMechanics::CreatureStats mCreatureStats; MWWorld::ContainerStore* mContainerStore; // may be InventoryStore for some creatures @@ -45,13 +45,13 @@ namespace virtual MWWorld::CustomData *clone() const; - CustomData() : mContainerStore(0) {} - virtual ~CustomData() { delete mContainerStore; } + CreatureCustomData() : mContainerStore(0) {} + virtual ~CreatureCustomData() { delete mContainerStore; } }; - MWWorld::CustomData *CustomData::clone() const + MWWorld::CustomData *CreatureCustomData::clone() const { - CustomData* cloned = new CustomData (*this); + CreatureCustomData* cloned = new CreatureCustomData (*this); cloned->mContainerStore = mContainerStore->clone(); return cloned; } @@ -63,7 +63,7 @@ namespace MWClass { if (!ptr.getRefData().getCustomData()) { - std::auto_ptr data (new CustomData); + std::auto_ptr data (new CreatureCustomData); static bool inited = false; if(!inited) @@ -192,7 +192,7 @@ namespace MWClass { ensureCustomData (ptr); - return dynamic_cast (*ptr.getRefData().getCustomData()).mCreatureStats; + return dynamic_cast (*ptr.getRefData().getCustomData()).mCreatureStats; } @@ -456,7 +456,7 @@ namespace MWClass { ensureCustomData (ptr); - return *dynamic_cast (*ptr.getRefData().getCustomData()).mContainerStore; + return *dynamic_cast (*ptr.getRefData().getCustomData()).mContainerStore; } MWWorld::InventoryStore& Creature::getInventoryStore(const MWWorld::Ptr &ptr) const @@ -559,7 +559,7 @@ namespace MWClass { ensureCustomData (ptr); - return dynamic_cast (*ptr.getRefData().getCustomData()).mMovement; + return dynamic_cast (*ptr.getRefData().getCustomData()).mMovement; } Ogre::Vector3 Creature::getMovementVector (const MWWorld::Ptr& ptr) const @@ -786,7 +786,7 @@ namespace MWClass ensureCustomData (ptr); - CustomData& customData = dynamic_cast (*ptr.getRefData().getCustomData()); + CreatureCustomData& customData = dynamic_cast (*ptr.getRefData().getCustomData()); customData.mContainerStore->readState (state2.mInventory); customData.mCreatureStats.readState (state2.mCreatureStats); @@ -800,7 +800,7 @@ namespace MWClass ensureCustomData (ptr); - CustomData& customData = dynamic_cast (*ptr.getRefData().getCustomData()); + CreatureCustomData& customData = dynamic_cast (*ptr.getRefData().getCustomData()); customData.mContainerStore->writeState (state2.mInventory); customData.mCreatureStats.writeState (state2.mCreatureStats); diff --git a/apps/openmw/mwclass/creaturelevlist.cpp b/apps/openmw/mwclass/creaturelevlist.cpp index caef521afb..732038b2fc 100644 --- a/apps/openmw/mwclass/creaturelevlist.cpp +++ b/apps/openmw/mwclass/creaturelevlist.cpp @@ -9,15 +9,15 @@ namespace { - struct CustomData : public MWWorld::CustomData + struct CreatureLevListCustomData : public MWWorld::CustomData { // TODO: save the creature we spawned here virtual MWWorld::CustomData *clone() const; }; - MWWorld::CustomData *CustomData::clone() const + MWWorld::CustomData *CreatureLevListCustomData::clone() const { - return new CustomData (*this); + return new CreatureLevListCustomData (*this); } } @@ -44,7 +44,7 @@ namespace MWClass { if (!ptr.getRefData().getCustomData()) { - std::auto_ptr data (new CustomData); + std::auto_ptr data (new CreatureLevListCustomData); MWWorld::LiveCellRef *ref = ptr.get(); diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index 72de620e44..bd25b66b2c 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -26,12 +26,12 @@ namespace { - struct CustomData : public MWWorld::CustomData + struct LightCustomData : public MWWorld::CustomData { float mTime; ///< Time remaining - CustomData(MWWorld::Ptr ptr) + LightCustomData(MWWorld::Ptr ptr) { MWWorld::LiveCellRef *ref = ptr.get(); mTime = ref->mBase->mData.mTime; @@ -40,7 +40,7 @@ namespace virtual MWWorld::CustomData *clone() const { - return new CustomData (*this); + return new LightCustomData (*this); } }; } @@ -210,7 +210,7 @@ namespace MWClass { ensureCustomData(ptr); - float &timeRemaining = dynamic_cast (*ptr.getRefData().getCustomData()).mTime; + float &timeRemaining = dynamic_cast (*ptr.getRefData().getCustomData()).mTime; timeRemaining = duration; } @@ -218,7 +218,7 @@ namespace MWClass { ensureCustomData(ptr); - return dynamic_cast (*ptr.getRefData().getCustomData()).mTime; + return dynamic_cast (*ptr.getRefData().getCustomData()).mTime; } MWWorld::Ptr @@ -233,7 +233,7 @@ namespace MWClass void Light::ensureCustomData (const MWWorld::Ptr& ptr) const { if (!ptr.getRefData().getCustomData()) - ptr.getRefData().setCustomData(new CustomData(ptr)); + ptr.getRefData().setCustomData(new LightCustomData(ptr)); } bool Light::canSell (const MWWorld::Ptr& item, int npcServices) const @@ -278,7 +278,7 @@ namespace MWClass ensureCustomData (ptr); - dynamic_cast (*ptr.getRefData().getCustomData()).mTime = state2.mTime; + dynamic_cast (*ptr.getRefData().getCustomData()).mTime = state2.mTime; } void Light::writeAdditionalState (const MWWorld::Ptr& ptr, ESM::ObjectState& state) @@ -288,6 +288,6 @@ namespace MWClass ensureCustomData (ptr); - state2.mTime = dynamic_cast (*ptr.getRefData().getCustomData()).mTime; + state2.mTime = dynamic_cast (*ptr.getRefData().getCustomData()).mTime; } } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index a1d2ef8481..3fbd0d5b21 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -39,7 +39,7 @@ namespace { - struct CustomData : public MWWorld::CustomData + struct NpcCustomData : public MWWorld::CustomData { MWMechanics::NpcStats mNpcStats; MWMechanics::Movement mMovement; @@ -48,9 +48,9 @@ namespace virtual MWWorld::CustomData *clone() const; }; - MWWorld::CustomData *CustomData::clone() const + MWWorld::CustomData *NpcCustomData::clone() const { - return new CustomData (*this); + return new NpcCustomData (*this); } void autoCalculateAttributes (const ESM::NPC* npc, MWMechanics::CreatureStats& creatureStats) @@ -262,7 +262,7 @@ namespace MWClass } if (!ptr.getRefData().getCustomData()) { - std::auto_ptr data(new CustomData); + std::auto_ptr data(new NpcCustomData); MWWorld::LiveCellRef *ref = ptr.get(); @@ -436,14 +436,14 @@ namespace MWClass { ensureCustomData (ptr); - return dynamic_cast (*ptr.getRefData().getCustomData()).mNpcStats; + return dynamic_cast (*ptr.getRefData().getCustomData()).mNpcStats; } MWMechanics::NpcStats& Npc::getNpcStats (const MWWorld::Ptr& ptr) const { ensureCustomData (ptr); - return dynamic_cast (*ptr.getRefData().getCustomData()).mNpcStats; + return dynamic_cast (*ptr.getRefData().getCustomData()).mNpcStats; } @@ -819,7 +819,7 @@ namespace MWClass { ensureCustomData (ptr); - return dynamic_cast (*ptr.getRefData().getCustomData()).mInventoryStore; + return dynamic_cast (*ptr.getRefData().getCustomData()).mInventoryStore; } MWWorld::InventoryStore& Npc::getInventoryStore (const MWWorld::Ptr& ptr) @@ -827,7 +827,7 @@ namespace MWClass { ensureCustomData (ptr); - return dynamic_cast (*ptr.getRefData().getCustomData()).mInventoryStore; + return dynamic_cast (*ptr.getRefData().getCustomData()).mInventoryStore; } std::string Npc::getScript (const MWWorld::Ptr& ptr) const @@ -841,7 +841,7 @@ namespace MWClass float Npc::getSpeed(const MWWorld::Ptr& ptr) const { const MWBase::World *world = MWBase::Environment::get().getWorld(); - const CustomData *npcdata = static_cast(ptr.getRefData().getCustomData()); + const NpcCustomData *npcdata = static_cast(ptr.getRefData().getCustomData()); const MWMechanics::MagicEffects &mageffects = npcdata->mNpcStats.getMagicEffects(); const float normalizedEncumbrance = Npc::getEncumbrance(ptr) / Npc::getCapacity(ptr); @@ -896,7 +896,7 @@ namespace MWClass float Npc::getJump(const MWWorld::Ptr &ptr) const { - const CustomData *npcdata = static_cast(ptr.getRefData().getCustomData()); + const NpcCustomData *npcdata = static_cast(ptr.getRefData().getCustomData()); const MWMechanics::MagicEffects &mageffects = npcdata->mNpcStats.getMagicEffects(); const float encumbranceTerm = fJumpEncumbranceBase->getFloat() + fJumpEncumbranceMultiplier->getFloat() * @@ -935,7 +935,7 @@ namespace MWClass if (fallHeight >= fallDistanceMin) { const float acrobaticsSkill = MWWorld::Class::get(ptr).getNpcStats (ptr).getSkill(ESM::Skill::Acrobatics).getModified(); - const CustomData *npcdata = static_cast(ptr.getRefData().getCustomData()); + const NpcCustomData *npcdata = static_cast(ptr.getRefData().getCustomData()); const float jumpSpellBonus = npcdata->mNpcStats.getMagicEffects().get(ESM::MagicEffect::Jump).mMagnitude; const float fallAcroBase = gmst.find("fFallAcroBase")->getFloat(); const float fallAcroMult = gmst.find("fFallAcroMult")->getFloat(); @@ -960,7 +960,7 @@ namespace MWClass { ensureCustomData (ptr); - return dynamic_cast (*ptr.getRefData().getCustomData()).mMovement; + return dynamic_cast (*ptr.getRefData().getCustomData()).mMovement; } Ogre::Vector3 Npc::getMovementVector (const MWWorld::Ptr& ptr) const @@ -1266,7 +1266,7 @@ namespace MWClass ensureCustomData (ptr); - CustomData& customData = dynamic_cast (*ptr.getRefData().getCustomData()); + NpcCustomData& customData = dynamic_cast (*ptr.getRefData().getCustomData()); customData.mInventoryStore.readState (state2.mInventory); customData.mNpcStats.readState (state2.mNpcStats); @@ -1280,7 +1280,7 @@ namespace MWClass ensureCustomData (ptr); - CustomData& customData = dynamic_cast (*ptr.getRefData().getCustomData()); + NpcCustomData& customData = dynamic_cast (*ptr.getRefData().getCustomData()); customData.mInventoryStore.writeState (state2.mInventory); customData.mNpcStats.writeState (state2.mNpcStats); diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index ddbd3f120d..a6880ffcb5 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -26,16 +26,6 @@ namespace return path; } - std::string getCountString(const int count) - { - if (count == 1) - return ""; - if (count > 9999) - return boost::lexical_cast(int(count/1000.f)) + "k"; - else - return boost::lexical_cast(count); - } - } namespace MWGui @@ -226,7 +216,7 @@ namespace MWGui text->setNeedMouseFocus(false); text->setTextShadow(true); text->setTextShadowColour(MyGUI::Colour(0,0,0)); - text->setCaption(getCountString(ingredient->getUserData()->getRefData().getCount())); + text->setCaption(ItemView::getCountString(ingredient->getUserData()->getRefData().getCount())); } mItemView->update(); diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 7e7ad5ec26..34ac8d9f4d 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -23,19 +23,6 @@ #include "sortfilteritemmodel.hpp" #include "pickpocketitemmodel.hpp" -namespace -{ - std::string getCountString(const int count) - { - if (count == 1) - return ""; - if (count > 9999) - return boost::lexical_cast(int(count/1000.f)) + "k"; - else - return boost::lexical_cast(count); - } -} - namespace MWGui { @@ -79,7 +66,7 @@ namespace MWGui text->setNeedMouseFocus(false); text->setTextShadow(true); text->setTextShadowColour(MyGUI::Colour(0,0,0)); - text->setCaption(getCountString(count)); + text->setCaption(ItemView::getCountString(count)); sourceView->update(); diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 481c983142..6b913f24ae 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -23,18 +23,7 @@ #include "travelwindow.hpp" #include "bookpage.hpp" - -namespace -{ - MWGui::BookTypesetter::Utf8Span to_utf8_span (char const * text) - { - typedef MWGui::BookTypesetter::Utf8Point point; - - point begin = reinterpret_cast (text); - - return MWGui::BookTypesetter::Utf8Span (begin, begin + strlen (text)); - } -} +#include "journalbooks.hpp" // to_utf8_span namespace MWGui { diff --git a/apps/openmw/mwgui/hud.hpp b/apps/openmw/mwgui/hud.hpp index 6d1ffd03c1..1645d8db01 100644 --- a/apps/openmw/mwgui/hud.hpp +++ b/apps/openmw/mwgui/hud.hpp @@ -1,3 +1,6 @@ +#ifndef OPENMW_GAME_MWGUI_HUD_H +#define OPENMW_GAME_MWGUI_HUD_H + #include "mapwindow.hpp" #include "../mwmechanics/stat.hpp" @@ -117,3 +120,5 @@ namespace MWGui void updatePositions(); }; } + +#endif diff --git a/apps/openmw/mwgui/itemselection.hpp b/apps/openmw/mwgui/itemselection.hpp index d6d19d9e1a..c9ec23cfae 100644 --- a/apps/openmw/mwgui/itemselection.hpp +++ b/apps/openmw/mwgui/itemselection.hpp @@ -1,3 +1,6 @@ +#ifndef OPENMW_GAME_MWGUI_ITEMSELECTION_H +#define OPENMW_GAME_MWGUI_ITEMSELECTION_H + #include "container.hpp" namespace MWGui @@ -32,3 +35,5 @@ namespace MWGui }; } + +#endif diff --git a/apps/openmw/mwgui/itemview.cpp b/apps/openmw/mwgui/itemview.cpp index f9a900ebac..027c3201fc 100644 --- a/apps/openmw/mwgui/itemview.cpp +++ b/apps/openmw/mwgui/itemview.cpp @@ -13,23 +13,19 @@ #include "itemmodel.hpp" -namespace -{ - std::string getCountString(const int count) - { - if (count == 1) - return ""; - if (count > 9999) - return boost::lexical_cast(int(count/1000.f)) + "k"; - else - return boost::lexical_cast(count); - } -} - - namespace MWGui { +std::string ItemView::getCountString(int count) +{ + if (count == 1) + return ""; + if (count > 9999) + return boost::lexical_cast(int(count/1000.f)) + "k"; + else + return boost::lexical_cast(count); +} + ItemView::ItemView() : mModel(NULL) , mScrollView(NULL) diff --git a/apps/openmw/mwgui/itemview.hpp b/apps/openmw/mwgui/itemview.hpp index 17f609f2b8..74bc66ea0d 100644 --- a/apps/openmw/mwgui/itemview.hpp +++ b/apps/openmw/mwgui/itemview.hpp @@ -30,6 +30,8 @@ namespace MWGui void update(); + static std::string getCountString(int count); + private: virtual void initialiseOverride(); diff --git a/apps/openmw/mwgui/journalbooks.cpp b/apps/openmw/mwgui/journalbooks.cpp index 8caea770ee..2682323cea 100644 --- a/apps/openmw/mwgui/journalbooks.cpp +++ b/apps/openmw/mwgui/journalbooks.cpp @@ -2,15 +2,6 @@ namespace { - MWGui::BookTypesetter::Utf8Span to_utf8_span (char const * text) - { - typedef MWGui::BookTypesetter::Utf8Point point; - - point begin = reinterpret_cast (text); - - return MWGui::BookTypesetter::Utf8Span (begin, begin + strlen (text)); - } - const MyGUI::Colour linkHot (0.40f, 0.40f, 0.80f); const MyGUI::Colour linkNormal (0.20f, 0.20f, 0.60f); const MyGUI::Colour linkActive (0.50f, 0.50f, 1.00f); diff --git a/apps/openmw/mwgui/journalbooks.hpp b/apps/openmw/mwgui/journalbooks.hpp index 09d3cf1a85..b9c0a60b3c 100644 --- a/apps/openmw/mwgui/journalbooks.hpp +++ b/apps/openmw/mwgui/journalbooks.hpp @@ -6,6 +6,15 @@ namespace MWGui { + MWGui::BookTypesetter::Utf8Span to_utf8_span (char const * text) + { + typedef MWGui::BookTypesetter::Utf8Point point; + + point begin = reinterpret_cast (text); + + return MWGui::BookTypesetter::Utf8Span (begin, begin + strlen (text)); + } + struct JournalBooks { typedef TypesetBook::Ptr Book; diff --git a/apps/openmw/mwgui/mainmenu.hpp b/apps/openmw/mwgui/mainmenu.hpp index 48b515d65b..722b329de1 100644 --- a/apps/openmw/mwgui/mainmenu.hpp +++ b/apps/openmw/mwgui/mainmenu.hpp @@ -1,3 +1,6 @@ +#ifndef OPENMW_GAME_MWGUI_MAINMENU_H +#define OPENMW_GAME_MWGUI_MAINMENU_H + #include #include "imagebutton.hpp" @@ -36,3 +39,5 @@ namespace MWGui }; } + +#endif diff --git a/apps/openmw/mwgui/quickkeysmenu.cpp b/apps/openmw/mwgui/quickkeysmenu.cpp index ff13ae1afa..ba4fdb86ab 100644 --- a/apps/openmw/mwgui/quickkeysmenu.cpp +++ b/apps/openmw/mwgui/quickkeysmenu.cpp @@ -20,28 +20,6 @@ #include "itemselection.hpp" -namespace -{ - bool sortItems(const MWWorld::Ptr& left, const MWWorld::Ptr& right) - { - int cmp = left.getClass().getName(left).compare( - right.getClass().getName(right)); - return cmp < 0; - } - - bool sortSpells(const std::string& left, const std::string& right) - { - const MWWorld::Store &spells = - MWBase::Environment::get().getWorld()->getStore().get(); - - const ESM::Spell* a = spells.find(left); - const ESM::Spell* b = spells.find(right); - - int cmp = a->mName.compare(b->mName); - return cmp < 0; - } -} - namespace MWGui { diff --git a/apps/openmw/mwgui/spellwindow.cpp b/apps/openmw/mwgui/spellwindow.cpp index 6b261a799c..19bd2e939c 100644 --- a/apps/openmw/mwgui/spellwindow.cpp +++ b/apps/openmw/mwgui/spellwindow.cpp @@ -18,28 +18,6 @@ #include "inventorywindow.hpp" #include "confirmationdialog.hpp" -namespace -{ - bool sortSpells(const std::string& left, const std::string& right) - { - const MWWorld::Store &spells = - MWBase::Environment::get().getWorld()->getStore().get(); - - const ESM::Spell* a = spells.find(left); - const ESM::Spell* b = spells.find(right); - - int cmp = a->mName.compare(b->mName); - return cmp < 0; - } - - bool sortItems(const MWWorld::Ptr& left, const MWWorld::Ptr& right) - { - int cmp = MWWorld::Class::get(left).getName(left).compare( - MWWorld::Class::get(right).getName(right)); - return cmp < 0; - } -} - namespace MWGui { SpellWindow::SpellWindow(DragAndDrop* drag) diff --git a/apps/openmw/mwgui/spellwindow.hpp b/apps/openmw/mwgui/spellwindow.hpp index 38a7619318..4699cc4455 100644 --- a/apps/openmw/mwgui/spellwindow.hpp +++ b/apps/openmw/mwgui/spellwindow.hpp @@ -7,6 +7,25 @@ namespace MWGui { class SpellIcons; + bool sortItems(const MWWorld::Ptr& left, const MWWorld::Ptr& right) + { + int cmp = left.getClass().getName(left).compare( + right.getClass().getName(right)); + return cmp < 0; + } + + bool sortSpells(const std::string& left, const std::string& right) + { + const MWWorld::Store &spells = + MWBase::Environment::get().getWorld()->getStore().get(); + + const ESM::Spell* a = spells.find(left); + const ESM::Spell* b = spells.find(right); + + int cmp = a->mName.compare(b->mName); + return cmp < 0; + } + class SpellWindow : public WindowPinnableBase, public NoDrop { public: diff --git a/apps/openmw/mwmechanics/aiactivate.cpp b/apps/openmw/mwmechanics/aiactivate.cpp index bdd7c8f3be..8610cf4b2d 100644 --- a/apps/openmw/mwmechanics/aiactivate.cpp +++ b/apps/openmw/mwmechanics/aiactivate.cpp @@ -10,16 +10,6 @@ #include "steering.hpp" #include "movement.hpp" -namespace -{ - float sgn(float a) - { - if(a > 0) - return 1.0; - return -1.0; - } -} - MWMechanics::AiActivate::AiActivate(const std::string &objectId) : mObjectId(objectId) { @@ -38,7 +28,7 @@ bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration) MWWorld::Ptr player = world->getPlayerPtr(); if(cell->mData.mX != player.getCell()->getCell()->mData.mX) { - int sideX = sgn(cell->mData.mX - player.getCell()->getCell()->mData.mX); + int sideX = PathFinder::sgn(cell->mData.mX - player.getCell()->getCell()->mData.mX); //check if actor is near the border of an inactive cell. If so, stop walking. if(sideX * (pos.pos[0] - cell->mData.mX*ESM::Land::REAL_SIZE) > sideX * (ESM::Land::REAL_SIZE/2.0f - 200.0f)) @@ -49,7 +39,7 @@ bool MWMechanics::AiActivate::execute (const MWWorld::Ptr& actor,float duration) } if(cell->mData.mY != player.getCell()->getCell()->mData.mY) { - int sideY = sgn(cell->mData.mY - player.getCell()->getCell()->mData.mY); + int sideY = PathFinder::sgn(cell->mData.mY - player.getCell()->getCell()->mData.mY); //check if actor is near the border of an inactive cell. If so, stop walking. if(sideY * (pos.pos[1] - cell->mData.mY*ESM::Land::REAL_SIZE) > sideY * (ESM::Land::REAL_SIZE/2.0f - 200.0f)) diff --git a/apps/openmw/mwmechanics/aiescort.cpp b/apps/openmw/mwmechanics/aiescort.cpp index b54f1d39ca..f27fada39f 100644 --- a/apps/openmw/mwmechanics/aiescort.cpp +++ b/apps/openmw/mwmechanics/aiescort.cpp @@ -11,16 +11,6 @@ #include "steering.hpp" #include "movement.hpp" -namespace -{ - float sgn(float a) - { - if(a > 0) - return 1.0; - return -1.0; - } -} - /* TODO: Test vanilla behavior on passing x0, y0, and z0 with duration of anything including 0. TODO: Different behavior for AIEscort a d x y z and AIEscortCell a c d x y z. @@ -91,7 +81,7 @@ namespace MWMechanics if(actor.getCell()->getCell()->mData.mX != player.getCell()->getCell()->mData.mX) { - int sideX = sgn(actor.getCell()->getCell()->mData.mX - player.getCell()->getCell()->mData.mX); + int sideX = PathFinder::sgn(actor.getCell()->getCell()->mData.mX - player.getCell()->getCell()->mData.mX); // Check if actor is near the border of an inactive cell. If so, pause walking. if(sideX * (pos.pos[0] - actor.getCell()->getCell()->mData.mX * ESM::Land::REAL_SIZE) > sideX * (ESM::Land::REAL_SIZE / 2.0 - 200)) @@ -102,7 +92,7 @@ namespace MWMechanics } if(actor.getCell()->getCell()->mData.mY != player.getCell()->getCell()->mData.mY) { - int sideY = sgn(actor.getCell()->getCell()->mData.mY - player.getCell()->getCell()->mData.mY); + int sideY = PathFinder::sgn(actor.getCell()->getCell()->mData.mY - player.getCell()->getCell()->mData.mY); // Check if actor is near the border of an inactive cell. If so, pause walking. if(sideY*(pos.pos[1] - actor.getCell()->getCell()->mData.mY * ESM::Land::REAL_SIZE) > sideY * (ESM::Land::REAL_SIZE / 2.0 - 200)) diff --git a/apps/openmw/mwmechanics/aitravel.cpp b/apps/openmw/mwmechanics/aitravel.cpp index 1fd719c608..c62c4e9702 100644 --- a/apps/openmw/mwmechanics/aitravel.cpp +++ b/apps/openmw/mwmechanics/aitravel.cpp @@ -9,16 +9,6 @@ #include "steering.hpp" #include "movement.hpp" -namespace -{ - float sgn(float a) - { - if(a > 0) - return 1.0; - return -1.0; - } -} - namespace MWMechanics { AiTravel::AiTravel(float x, float y, float z) @@ -43,7 +33,7 @@ namespace MWMechanics MWWorld::Ptr player = world->getPlayerPtr(); if(cell->mData.mX != player.getCell()->getCell()->mData.mX) { - int sideX = sgn(cell->mData.mX - player.getCell()->getCell()->mData.mX); + int sideX = PathFinder::sgn(cell->mData.mX - player.getCell()->getCell()->mData.mX); //check if actor is near the border of an inactive cell. If so, stop walking. if(sideX * (pos.pos[0] - cell->mData.mX*ESM::Land::REAL_SIZE) > sideX * (ESM::Land::REAL_SIZE/2.0f - 200.0f)) @@ -54,7 +44,7 @@ namespace MWMechanics } if(cell->mData.mY != player.getCell()->getCell()->mData.mY) { - int sideY = sgn(cell->mData.mY - player.getCell()->getCell()->mData.mY); + int sideY = PathFinder::sgn(cell->mData.mY - player.getCell()->getCell()->mData.mY); //check if actor is near the border of an inactive cell. If so, stop walking. if(sideY * (pos.pos[1] - cell->mData.mY*ESM::Land::REAL_SIZE) > sideY * (ESM::Land::REAL_SIZE/2.0f - 200.0f)) diff --git a/apps/openmw/mwmechanics/aiwander.cpp b/apps/openmw/mwmechanics/aiwander.cpp index 4da325abd6..2db875a01b 100644 --- a/apps/openmw/mwmechanics/aiwander.cpp +++ b/apps/openmw/mwmechanics/aiwander.cpp @@ -15,16 +15,6 @@ #include "steering.hpp" #include "movement.hpp" -namespace -{ - float sgn(float a) - { - if(a > 0) - return 1.0; - return -1.0; - } -} - namespace MWMechanics { // NOTE: determined empirically but probably need further tweaking diff --git a/apps/openmw/mwmechanics/pathfinding.cpp b/apps/openmw/mwmechanics/pathfinding.cpp index 5314b5919c..3ecd407431 100644 --- a/apps/openmw/mwmechanics/pathfinding.cpp +++ b/apps/openmw/mwmechanics/pathfinding.cpp @@ -37,13 +37,6 @@ namespace return sqrt(x * x + y * y + z * z); } - static float sgn(Ogre::Radian a) - { - if(a.valueRadians() > 0) - return 1.0; - return -1.0; - } - int getClosestPoint(const ESM::Pathgrid* grid, float x, float y, float z) { if(!grid || grid->mPoints.empty()) diff --git a/apps/openmw/mwmechanics/pathfinding.hpp b/apps/openmw/mwmechanics/pathfinding.hpp index 8771ef0cad..ecaaef568f 100644 --- a/apps/openmw/mwmechanics/pathfinding.hpp +++ b/apps/openmw/mwmechanics/pathfinding.hpp @@ -4,6 +4,8 @@ #include #include +#include + namespace MWWorld { class CellStore; @@ -16,6 +18,20 @@ namespace MWMechanics public: PathFinder(); + static float sgn(Ogre::Radian a) + { + if(a.valueRadians() > 0) + return 1.0; + return -1.0; + } + + static float sgn(float a) + { + if(a > 0) + return 1.0; + return -1.0; + } + void clearPath(); void buildPathgridGraph(const ESM::Pathgrid* pathGrid); diff --git a/apps/openmw/mwscript/containerextensions.cpp b/apps/openmw/mwscript/containerextensions.cpp index d489bfaf15..66c8d44687 100644 --- a/apps/openmw/mwscript/containerextensions.cpp +++ b/apps/openmw/mwscript/containerextensions.cpp @@ -121,7 +121,7 @@ namespace MWScript std::string itemName; for (MWWorld::ContainerStoreIterator iter(store.begin()); iter != store.end(); ++iter) - if (Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, item)) + if (::Misc::StringUtils::ciEqual(iter->getCellRef().mRefID, item)) itemName = iter->getClass().getName(*iter); int numRemoved = store.remove(item, count, ptr); @@ -165,7 +165,7 @@ namespace MWScript MWWorld::ContainerStoreIterator it = invStore.begin(); for (; it != invStore.end(); ++it) { - if (Misc::StringUtils::ciEqual(it->getCellRef().mRefID, item)) + if (::Misc::StringUtils::ciEqual(it->getCellRef().mRefID, item)) break; } if (it == invStore.end()) @@ -268,7 +268,7 @@ namespace MWScript for (int slot = 0; slot < MWWorld::InventoryStore::Slots; ++slot) { MWWorld::ContainerStoreIterator it = invStore.getSlot (slot); - if (it != invStore.end() && Misc::StringUtils::ciEqual(it->getCellRef().mRefID, item)) + if (it != invStore.end() && ::Misc::StringUtils::ciEqual(it->getCellRef().mRefID, item)) { runtime.push(1); return; @@ -295,7 +295,7 @@ namespace MWScript it != invStore.end(); ++it) { - if (Misc::StringUtils::ciEqual(it->getCellRef().mSoul, name)) + if (::Misc::StringUtils::ciEqual(it->getCellRef().mSoul, name)) { runtime.push(1); return; diff --git a/apps/openmw/mwscript/globalscripts.cpp b/apps/openmw/mwscript/globalscripts.cpp index 179e2bb0bb..527c576cc7 100644 --- a/apps/openmw/mwscript/globalscripts.cpp +++ b/apps/openmw/mwscript/globalscripts.cpp @@ -24,7 +24,7 @@ namespace MWScript void GlobalScripts::addScript (const std::string& name) { std::map >::iterator iter = - mScripts.find (Misc::StringUtils::lowerCase (name)); + mScripts.find (::Misc::StringUtils::lowerCase (name)); if (iter==mScripts.end()) { @@ -44,7 +44,7 @@ namespace MWScript void GlobalScripts::removeScript (const std::string& name) { std::map >::iterator iter = - mScripts.find (Misc::StringUtils::lowerCase (name)); + mScripts.find (::Misc::StringUtils::lowerCase (name)); if (iter!=mScripts.end()) iter->second.first = false; @@ -53,7 +53,7 @@ namespace MWScript bool GlobalScripts::isRunning (const std::string& name) const { std::map >::const_iterator iter = - mScripts.find (Misc::StringUtils::lowerCase (name)); + mScripts.find (::Misc::StringUtils::lowerCase (name)); if (iter==mScripts.end()) return false; @@ -151,7 +151,7 @@ namespace MWScript Locals& GlobalScripts::getLocals (const std::string& name) { - std::string name2 = Misc::StringUtils::lowerCase (name); + std::string name2 = ::Misc::StringUtils::lowerCase (name); std::map >::iterator iter = mScripts.find (name2); diff --git a/apps/openmw/mwscript/guiextensions.cpp b/apps/openmw/mwscript/guiextensions.cpp index ab8901881b..57fc2d4707 100644 --- a/apps/openmw/mwscript/guiextensions.cpp +++ b/apps/openmw/mwscript/guiextensions.cpp @@ -113,7 +113,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { std::string cell = (runtime.getStringLiteral (runtime[0].mInteger)); - Misc::StringUtils::toLower(cell); + ::Misc::StringUtils::toLower(cell); runtime.pop(); // "Will match complete or partial cells, so ShowMap, "Vivec" will show cells Vivec and Vivec, Fred's House as well." @@ -126,7 +126,7 @@ namespace MWScript for (; it != cells.extEnd(); ++it) { std::string name = it->mName; - Misc::StringUtils::toLower(name); + ::Misc::StringUtils::toLower(name); if (name.find(cell) != std::string::npos) MWBase::Environment::get().getWindowManager()->addVisitedLocation ( it->mName, diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index c4f672dc76..80467f58ad 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -540,7 +540,7 @@ namespace MWScript factionID = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); } - Misc::StringUtils::toLower(factionID); + ::Misc::StringUtils::toLower(factionID); if(factionID != "") { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); @@ -569,7 +569,7 @@ namespace MWScript factionID = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); } - Misc::StringUtils::toLower(factionID); + ::Misc::StringUtils::toLower(factionID); if(factionID != "") { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); @@ -602,7 +602,7 @@ namespace MWScript factionID = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); } - Misc::StringUtils::toLower(factionID); + ::Misc::StringUtils::toLower(factionID); if(factionID != "") { MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); @@ -640,7 +640,7 @@ namespace MWScript factionID = MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().begin()->first; } } - Misc::StringUtils::toLower(factionID); + ::Misc::StringUtils::toLower(factionID); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if(factionID!="") { @@ -742,7 +742,7 @@ namespace MWScript if (factionId.empty()) throw std::runtime_error ("failed to determine faction"); - Misc::StringUtils::toLower (factionId); + ::Misc::StringUtils::toLower (factionId); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); runtime.push ( @@ -778,7 +778,7 @@ namespace MWScript if (factionId.empty()) throw std::runtime_error ("failed to determine faction"); - Misc::StringUtils::toLower (factionId); + ::Misc::StringUtils::toLower (factionId); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Class::get (player).getNpcStats (player).setFactionReputation (factionId, value); @@ -813,7 +813,7 @@ namespace MWScript if (factionId.empty()) throw std::runtime_error ("failed to determine faction"); - Misc::StringUtils::toLower (factionId); + ::Misc::StringUtils::toLower (factionId); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); MWWorld::Class::get (player).getNpcStats (player).setFactionReputation (factionId, @@ -858,11 +858,11 @@ namespace MWScript MWWorld::Ptr ptr = R()(runtime); std::string race = runtime.getStringLiteral(runtime[0].mInteger); - Misc::StringUtils::toLower(race); + ::Misc::StringUtils::toLower(race); runtime.pop(); std::string npcRace = ptr.get()->mBase->mRace; - Misc::StringUtils::toLower(npcRace); + ::Misc::StringUtils::toLower(npcRace); runtime.push (npcRace == race); } @@ -906,7 +906,7 @@ namespace MWScript factionID = MWWorld::Class::get(ptr).getNpcStats(ptr).getFactionRanks().begin()->first; } } - Misc::StringUtils::toLower(factionID); + ::Misc::StringUtils::toLower(factionID); MWWorld::Ptr player = MWBase::Environment::get().getWorld()->getPlayerPtr(); if(factionID!="") { diff --git a/apps/openmw/mwsound/ffmpeg_decoder.cpp b/apps/openmw/mwsound/ffmpeg_decoder.cpp index c836974425..c595de5aec 100644 --- a/apps/openmw/mwsound/ffmpeg_decoder.cpp +++ b/apps/openmw/mwsound/ffmpeg_decoder.cpp @@ -11,9 +11,10 @@ namespace MWSound { -static void fail(const std::string &msg) -{ throw std::runtime_error("FFmpeg exception: "+msg); } - +void FFmpeg_Decoder::fail(const std::string &msg) +{ + throw std::runtime_error("FFmpeg exception: "+msg); +} int FFmpeg_Decoder::readPacket(void *user_data, uint8_t *buf, int buf_size) { diff --git a/apps/openmw/mwsound/ffmpeg_decoder.hpp b/apps/openmw/mwsound/ffmpeg_decoder.hpp index d0d73379d3..8276b45c77 100644 --- a/apps/openmw/mwsound/ffmpeg_decoder.hpp +++ b/apps/openmw/mwsound/ffmpeg_decoder.hpp @@ -61,6 +61,8 @@ namespace MWSound virtual void rewind(); virtual size_t getSampleOffset(); + void fail(const std::string &msg); + FFmpeg_Decoder& operator=(const FFmpeg_Decoder &rhs); FFmpeg_Decoder(const FFmpeg_Decoder &rhs); diff --git a/components/bsa/bsa_file.cpp b/components/bsa/bsa_file.cpp index 8db4fa8888..25b006fb3e 100644 --- a/components/bsa/bsa_file.cpp +++ b/components/bsa/bsa_file.cpp @@ -111,7 +111,7 @@ void BSAFile::readHeader() fail("Directory information larger than entire archive"); // Read the offset info into a temporary buffer - vector offsets(3*filenum); + std::vector offsets(3*filenum); input.read(reinterpret_cast(&offsets[0]), 12*filenum); // Read the string table diff --git a/components/compiler/declarationparser.cpp b/components/compiler/declarationparser.cpp index d17f49caf0..7961b8f411 100644 --- a/components/compiler/declarationparser.cpp +++ b/components/compiler/declarationparser.cpp @@ -18,7 +18,7 @@ bool Compiler::DeclarationParser::parseName (const std::string& name, const Toke { if (mState==State_Name) { - std::string name2 = Misc::StringUtils::lowerCase (name); + std::string name2 = ::Misc::StringUtils::lowerCase (name); char type = mLocals.getType (name2); @@ -80,4 +80,4 @@ bool Compiler::DeclarationParser::parseSpecial (int code, const TokenLoc& loc, S void Compiler::DeclarationParser::reset() { mState = State_Begin; -} \ No newline at end of file +} diff --git a/components/interpreter/runtime.cpp b/components/interpreter/runtime.cpp index bb0dffb87f..c71aef95c5 100644 --- a/components/interpreter/runtime.cpp +++ b/components/interpreter/runtime.cpp @@ -50,7 +50,7 @@ namespace Interpreter return literalBlock+offset; } - void Runtime::configure (const Interpreter::Type_Code *code, int codeSize, Context& context) + void Runtime::configure (const Type_Code *code, int codeSize, Context& context) { clear(); From 9089df30807e8479b7a87aeba31ee6bce21f6a4d Mon Sep 17 00:00:00 2001 From: scrawl Date: Sun, 16 Mar 2014 23:40:59 +0100 Subject: [PATCH 058/127] Add unity build option Each component and each MW-subsystem will be used as a single compilation unit. --- CMakeLists.txt | 2 + cmake/OpenMWMacros.cmake | 85 +++++++++++++++++++++++++++++++--------- 2 files changed, 69 insertions(+), 18 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 954e161a1d..154f30161b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -73,6 +73,8 @@ option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binarie option(BOOST_STATIC "Link static build of Boost into the binaries" FALSE) option(SDL2_STATIC "Link static build of SDL into the binaries" FALSE) +option(OPENMW_UNITY_BUILD "Use fewer compilation units to speed up compile time" FALSE) + # Apps and tools option(BUILD_BSATOOL "build BSA extractor" OFF) option(BUILD_ESMTOOL "build ESM inspector" ON) diff --git a/cmake/OpenMWMacros.cmake b/cmake/OpenMWMacros.cmake index f66dbf2c47..c5669fa70c 100644 --- a/cmake/OpenMWMacros.cmake +++ b/cmake/OpenMWMacros.cmake @@ -1,26 +1,75 @@ +function(enable_unity_build UB_SUFFIX SOURCE_VARIABLE_NAME) + set(files ${SOURCE_VARIABLE_NAME}) + # Generate a unique filename for the unity build translation unit + set(unit_build_file ${CMAKE_CURRENT_BINARY_DIR}/ub_${UB_SUFFIX}.cpp) + # Exclude all translation units from compilation + set_source_files_properties(${files} PROPERTIES HEADER_FILE_ONLY true) + # Open the ub file + FILE(WRITE ${unit_build_file} "// Unity Build generated by CMake\n") + # Add include statement for each translation unit + foreach(source_file ${files} ) + FILE( APPEND ${unit_build_file} "#include <${source_file}>\n") + endforeach(source_file) + # Complement list of translation units with the name of ub + set(${SOURCE_VARIABLE_NAME} ${${SOURCE_VARIABLE_NAME}} ${unit_build_file} PARENT_SCOPE) +endfunction(enable_unity_build) + + macro (add_openmw_dir dir) -set (files) -foreach (u ${ARGN}) -file (GLOB ALL "${dir}/${u}.[ch]pp") -foreach (f ${ALL}) -list (APPEND files "${f}") -list (APPEND OPENMW_FILES "${f}") -endforeach (f) -endforeach (u) -source_group ("apps\\openmw\\${dir}" FILES ${files}) + set (files) + set (cppfiles) + foreach (u ${ARGN}) + + # Add cpp and hpp to OPENMW_FILES + file (GLOB ALL "${dir}/${u}.[ch]pp") + foreach (f ${ALL}) + list (APPEND files "${f}") + list (APPEND OPENMW_FILES "${f}") + endforeach (f) + + # Add cpp to unity build + file (GLOB ALL "${dir}/${u}.cpp") + foreach (f ${ALL}) + list (APPEND cppfiles "${f}") + endforeach (f) + + endforeach (u) + + if (OPENMW_UNITY_BUILD) + enable_unity_build(${dir} "${cppfiles}") + list (APPEND OPENMW_FILES ${CMAKE_CURRENT_BINARY_DIR}/ub_${dir}.cpp) + endif() + + source_group ("apps\\openmw\\${dir}" FILES ${files}) endmacro (add_openmw_dir) macro (add_component_dir dir) -set (files) -foreach (u ${ARGN}) -file (GLOB ALL "${dir}/${u}.[ch]pp") -foreach (f ${ALL}) -list (APPEND files "${f}") -list (APPEND COMPONENT_FILES "${f}") -endforeach (f) -endforeach (u) -source_group ("components\\${dir}" FILES ${files}) + set (files) + set (cppfiles) + + foreach (u ${ARGN}) + file (GLOB ALL "${dir}/${u}.[ch]pp") + + foreach (f ${ALL}) + list (APPEND files "${f}") + list (APPEND COMPONENT_FILES "${f}") + endforeach (f) + + # Add cpp to unity build + file (GLOB ALL "${dir}/${u}.cpp") + foreach (f ${ALL}) + list (APPEND cppfiles "${f}") + endforeach (f) + + endforeach (u) + + if (OPENMW_UNITY_BUILD) + enable_unity_build(${dir} "${cppfiles}") + list (APPEND COMPONENT_FILES ${CMAKE_CURRENT_BINARY_DIR}/ub_${dir}.cpp) + endif() + + source_group ("components\\${dir}" FILES ${files}) endmacro (add_component_dir) macro (add_component_qt_dir dir) From 4443e22387611bea47a7050a7df35ddf364fa738 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 17 Mar 2014 13:21:28 +0100 Subject: [PATCH 059/127] Build fix --- apps/openmw/mwgui/quickkeysmenu.cpp | 2 ++ apps/openmw/mwgui/spellwindow.cpp | 20 ++++++++++++++++++++ apps/openmw/mwgui/spellwindow.hpp | 20 +++----------------- 3 files changed, 25 insertions(+), 17 deletions(-) diff --git a/apps/openmw/mwgui/quickkeysmenu.cpp b/apps/openmw/mwgui/quickkeysmenu.cpp index ba4fdb86ab..4c0faeac1f 100644 --- a/apps/openmw/mwgui/quickkeysmenu.cpp +++ b/apps/openmw/mwgui/quickkeysmenu.cpp @@ -19,6 +19,8 @@ #include "windowmanagerimp.hpp" #include "itemselection.hpp" +#include "spellwindow.hpp" + namespace MWGui { diff --git a/apps/openmw/mwgui/spellwindow.cpp b/apps/openmw/mwgui/spellwindow.cpp index 19bd2e939c..b052739bda 100644 --- a/apps/openmw/mwgui/spellwindow.cpp +++ b/apps/openmw/mwgui/spellwindow.cpp @@ -20,6 +20,26 @@ namespace MWGui { + + bool sortItems(const MWWorld::Ptr& left, const MWWorld::Ptr& right) + { + int cmp = left.getClass().getName(left).compare( + right.getClass().getName(right)); + return cmp < 0; + } + + bool sortSpells(const std::string& left, const std::string& right) + { + const MWWorld::Store &spells = + MWBase::Environment::get().getWorld()->getStore().get(); + + const ESM::Spell* a = spells.find(left); + const ESM::Spell* b = spells.find(right); + + int cmp = a->mName.compare(b->mName); + return cmp < 0; + } + SpellWindow::SpellWindow(DragAndDrop* drag) : WindowPinnableBase("openmw_spell_window.layout") , NoDrop(drag, mMainWidget) diff --git a/apps/openmw/mwgui/spellwindow.hpp b/apps/openmw/mwgui/spellwindow.hpp index 4699cc4455..53eed1ba14 100644 --- a/apps/openmw/mwgui/spellwindow.hpp +++ b/apps/openmw/mwgui/spellwindow.hpp @@ -2,29 +2,15 @@ #define MWGUI_SPELLWINDOW_H #include "windowpinnablebase.hpp" +#include "../mwworld/ptr.hpp" namespace MWGui { class SpellIcons; - bool sortItems(const MWWorld::Ptr& left, const MWWorld::Ptr& right) - { - int cmp = left.getClass().getName(left).compare( - right.getClass().getName(right)); - return cmp < 0; - } + bool sortItems(const MWWorld::Ptr& left, const MWWorld::Ptr& right); - bool sortSpells(const std::string& left, const std::string& right) - { - const MWWorld::Store &spells = - MWBase::Environment::get().getWorld()->getStore().get(); - - const ESM::Spell* a = spells.find(left); - const ESM::Spell* b = spells.find(right); - - int cmp = a->mName.compare(b->mName); - return cmp < 0; - } + bool sortSpells(const std::string& left, const std::string& right); class SpellWindow : public WindowPinnableBase, public NoDrop { From 128a47570e07e7d862f3f59bb66f8153e34481e0 Mon Sep 17 00:00:00 2001 From: scrawl Date: Mon, 17 Mar 2014 14:15:52 +0100 Subject: [PATCH 060/127] One more fix --- apps/openmw/mwgui/journalbooks.cpp | 9 +++++++++ apps/openmw/mwgui/journalbooks.hpp | 9 +-------- 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/apps/openmw/mwgui/journalbooks.cpp b/apps/openmw/mwgui/journalbooks.cpp index 2682323cea..683fe9208f 100644 --- a/apps/openmw/mwgui/journalbooks.cpp +++ b/apps/openmw/mwgui/journalbooks.cpp @@ -169,6 +169,15 @@ namespace namespace MWGui { +MWGui::BookTypesetter::Utf8Span to_utf8_span (char const * text) +{ + typedef MWGui::BookTypesetter::Utf8Point point; + + point begin = reinterpret_cast (text); + + return MWGui::BookTypesetter::Utf8Span (begin, begin + strlen (text)); +} + typedef TypesetBook::Ptr book; JournalBooks::JournalBooks (JournalViewModel::Ptr model) : diff --git a/apps/openmw/mwgui/journalbooks.hpp b/apps/openmw/mwgui/journalbooks.hpp index b9c0a60b3c..819bda0fd2 100644 --- a/apps/openmw/mwgui/journalbooks.hpp +++ b/apps/openmw/mwgui/journalbooks.hpp @@ -6,14 +6,7 @@ namespace MWGui { - MWGui::BookTypesetter::Utf8Span to_utf8_span (char const * text) - { - typedef MWGui::BookTypesetter::Utf8Point point; - - point begin = reinterpret_cast (text); - - return MWGui::BookTypesetter::Utf8Span (begin, begin + strlen (text)); - } + MWGui::BookTypesetter::Utf8Span to_utf8_span (char const * text); struct JournalBooks { From 09ba54763024059bc179d06ffafd89d23a520eec Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 17 Mar 2014 15:35:36 +0100 Subject: [PATCH 061/127] use tool buttons with icons --- apps/opencs/view/world/dialoguesubview.cpp | 12 ++++++++---- files/opencs/go-next.png | Bin 0 -> 930 bytes files/opencs/go-previous.png | Bin 0 -> 955 bytes files/opencs/resources.qrc | 2 ++ 4 files changed, 10 insertions(+), 4 deletions(-) create mode 100644 files/opencs/go-next.png create mode 100644 files/opencs/go-previous.png diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 2e77cf29e0..660bb305fb 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -19,6 +19,7 @@ #include #include #include +#include #include "../../model/world/columnbase.hpp" #include "../../model/world/idtable.hpp" @@ -394,10 +395,13 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM QWidget *mainWidget = new QWidget(this); QHBoxLayout *buttonsLayout = new QHBoxLayout; - QPushButton* prevButton = new QPushButton(tr("Previous"), mainWidget); - QPushButton* nextButton = new QPushButton(tr("Next"), mainWidget); - buttonsLayout->addWidget(prevButton); - buttonsLayout->addWidget(nextButton); + QToolButton* prevButton = new QToolButton(mainWidget); + prevButton->setIcon(QIcon(":/go-previous.png")); + QToolButton* nextButton = new QToolButton(mainWidget); + nextButton->setIcon(QIcon(":/go-next.png")); + buttonsLayout->addWidget(prevButton, 0); + buttonsLayout->addWidget(nextButton, 1); + buttonsLayout->addStretch(2); connect(nextButton, SIGNAL(clicked()), this, SLOT(nextId())); connect(prevButton, SIGNAL(clicked()), this, SLOT(prevId())); diff --git a/files/opencs/go-next.png b/files/opencs/go-next.png new file mode 100644 index 0000000000000000000000000000000000000000..6f3f65d33d303315f0d8d9dd03c7e7e2427d4950 GIT binary patch literal 930 zcmV;T16}-yP)b zm0M^XRTPH5HM8gBV(mpKDJa$_Z|#GH3N?w)f>s1UMXmZGQl%7pX-P>7f}&tiq(1aT zP)ljdLx@@mDPl`Bh9;&enie%Q#!J+svBm_`ljO{0&t5*9IdzgY(T8-w&&-B3-`fA$ zi`k;8T#fLq3ibbj8=Hf!`X=+>l7rQ;d2QV-?>9CVb}uOyV8_ERRIj^vt-Jr}^J`7#mgi;JV)-V&XlM@pz)^Qubt9p3w))KZP8v6Cty-~c zRl~=9ZT*|}%9hiw>&TVBk{`E*J%R4u*)k_V)uAX(9bH4M2p)H=X<%%8)E(<;`P*81 z@8<{N{{IBOvg2J&{nVa86~&Rd6sHcSmeg5NwcJ*BHyV2!{p9dWDJ(v9>J8g5$L0J= zsk213L}W|EX-H&4k~AVoLt+~ery;Q|@y+iixR{RdYHa50=@ zc;Z`>a*MNG;dVYeab$LCdg4%TZMthga6bIN!w)=6m3OItX9Q0?*00)%Kf9c^j>EIlQ#1Qc zA57l?;H7zB5ee#>%FD+$>_Y(0NEvPf-v}qi-lVpshC8o+i1CprJ$AfhX7ZQl+3(t2 zH&6>05s6eaF&WeV1%>gq+V-!$Z0APe-Os&PsP>n$@w!Jj_x-uF^Rtr^!@atFw9gFz zHT*jWDk5oR$3Ecq9kAr&;el~2&q-4lO(_RF6KKCrtkj_?;y0348J zvVd8%$N30LAs>C(5f2Uy_MAE5UP~ip7D;y%aK4(KDFy_}Bhr4nHU9O7(L-n7bFEo! zk}1x<%d6Z9Rkb2Q1|nz80wzuLs~`JES_Y1~?yQi@K`QVBC;_3W>YRUtl<7g%+ko=a zR2)dofzERo0gb zl}%_|RTze!@0@e*&7V^HBN&Y|1&xTHg2tGcEZQg$sloamid{(QrYma`p)R6`8xe$x zE=)JAVs%lCB0?>;8x67IczQ|E_9Y~NZ8{U=yn5|bNt zZ{FN-`>T5f542e0(zO_A*m+=BT65yYyKmi^zpwkzroe@3VKxTmpO<#Qo$9}PN9Ubg z_Xgiie@@TlL5!nPUT}-K{lP!##V{MR`u1A(tAcYQ;T_gAofzD<^P1~6-C!rCJ_VE{ zO?Y9~Tg^rcf*`V-pKddeGBNcDMl99@d@*?#BMu`5 zYb=66M96P>ym1t{;b7mot2ey7qkmV+`Nb)IK6?gh0-Om*H6=|GtZ^8z_|#xB$4MHa zD6$$jKjIFyZ|rzxApcm)!!tZo00$ zhq5n{niALwE`qSx617;GS}jp)^&B)CQmI@XtfQKK{hHtR*X)JiW5*8{*M}YSbUs87 z1lYjfLPHRlDtrlQago7TL4k#H%e?#y8Bg9ja)0mkw!Y3Mr7-(3 zYAQUqh^+o!nj9Hs){H z=}ylcLsNMD&@1I~F^*P_E-*KL76XJLlGGgAOs=NizD)j@|COP{pFB8!alR|pGZbnf z#AOW%WB!5iMHYZ^rc$=oSgzquXnvZ7!rRH-LgDnu&rXb&7mKAv<@GDAIZiV9I`7ewn;fJhF#0jl@vQT*g_QU!iIgs_I1~i>lhOu8{-W_eYbl%HYh8>o&{o zBxWuf-PgfmU=b*(s!IKhkt#g^qHK3{6G$e_R6k`ID61~NDss8UR75P*@7&g@Hcf4! d1W0rh$lr11Sh~C<&aD6d002ovPDHLkV1hiw#cluq literal 0 HcmV?d00001 diff --git a/files/opencs/resources.qrc b/files/opencs/resources.qrc index 2b1e65ff03..fb3c1eb3e9 100644 --- a/files/opencs/resources.qrc +++ b/files/opencs/resources.qrc @@ -57,6 +57,8 @@ static.png weapon.png multitype.png + go-next.png + go-previous.png raster/startup/big/create-addon.png raster/startup/big/new-game.png raster/startup/big/edit-content.png From 7296b09357b2aa3bfec4ed2a375404a96b3130bd Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 17 Mar 2014 19:18:18 +0100 Subject: [PATCH 062/127] revert button --- apps/opencs/view/world/dialoguesubview.cpp | 43 ++++++++++++++++++++++ apps/opencs/view/world/dialoguesubview.hpp | 2 + 2 files changed, 45 insertions(+) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 660bb305fb..8f602aa8d3 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -27,6 +27,7 @@ #include "../../model/world/record.hpp" #include "../../model/world/tablemimedata.hpp" #include "../../model/doc/document.hpp" +#include "../../model/world/commands.hpp" #include "recordstatusdelegate.hpp" #include "util.hpp" @@ -402,9 +403,22 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM buttonsLayout->addWidget(prevButton, 0); buttonsLayout->addWidget(nextButton, 1); buttonsLayout->addStretch(2); + + QToolButton* cloneButton = new QToolButton(mainWidget); + QToolButton* addButton = new QToolButton(mainWidget); + QToolButton* deleteButton = new QToolButton(mainWidget); + QToolButton* revertButton = new QToolButton(mainWidget); + + 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(revertButton, SIGNAL(clicked()), this, SLOT(revertRecord())); + mMainLayout = new QVBoxLayout(mainWidget); mEditWidget = new EditWidget(mainWidget, mRow, mTable, mUndoStack, false); @@ -519,3 +533,32 @@ void CSVWorld::DialogueSubView::tableMimeDataDropped(QWidget* editor, qobject_cast(editor)->setText(id.getId().c_str()); } } + +void CSVWorld::DialogueSubView::revertRecord() +{ + int rows = mTable->rowCount(); + if (!mLocked && mTable->columnCount() > 0 && mRow < mTable->rowCount() ) + { + CSMWorld::RecordBase::State state = + static_cast (mTable->data (mTable->index (mRow, 1)).toInt()); + + if (state!=CSMWorld::RecordBase::State_BaseOnly) + { + mUndoStack.push(new CSMWorld::RevertCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toStdString())); + } + if (rows != mTable->rowCount()) + { + if (mTable->rowCount() == 0) + { + mEditWidget->setDisabled(true); + return; + } + if (mRow >= mTable->rowCount()) + { + prevId(); + } else { + dataChanged(mTable->index(mRow, 0)); + } + } + } +} \ No newline at end of file diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index c2e7da3382..b7920a3874 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -179,6 +179,8 @@ namespace CSVWorld void prevId(); + void revertRecord(); + void dataChanged(const QModelIndex & index); ///\brief we need to care for deleting currently edited record From 95afca0558c732af60a2fb5c4b5589185f6d7a26 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Mon, 17 Mar 2014 19:28:41 +0100 Subject: [PATCH 063/127] delete record button --- apps/opencs/view/world/dialoguesubview.cpp | 26 +++++++++++++++++++++- apps/opencs/view/world/dialoguesubview.hpp | 1 + 2 files changed, 26 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 8f602aa8d3..6bd8001c7a 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -418,6 +418,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM connect(prevButton, SIGNAL(clicked()), this, SLOT(prevId())); connect(revertButton, SIGNAL(clicked()), this, SLOT(revertRecord())); + connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteRecord())); mMainLayout = new QVBoxLayout(mainWidget); @@ -550,7 +551,30 @@ void CSVWorld::DialogueSubView::revertRecord() { if (mTable->rowCount() == 0) { - mEditWidget->setDisabled(true); + mEditWidget->setDisabled(true); //closing the editor is other option + return; + } + if (mRow >= mTable->rowCount()) + { + prevId(); + } else { + dataChanged(mTable->index(mRow, 0)); + } + } + } +} + +void CSVWorld::DialogueSubView::deleteRecord() +{ + int rows = mTable->rowCount(); + if (!mLocked && mTable->columnCount() > 0 && mRow < mTable->rowCount() ) + { + mUndoStack.push(new CSMWorld::DeleteCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toStdString())); + if (rows != mTable->rowCount()) + { + if (mTable->rowCount() == 0) + { + mEditWidget->setDisabled(true); //closing the editor is other option return; } if (mRow >= mTable->rowCount()) diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index b7920a3874..bf6e70e0d3 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -180,6 +180,7 @@ namespace CSVWorld void prevId(); void revertRecord(); + void deleteRecord(); void dataChanged(const QModelIndex & index); ///\brief we need to care for deleting currently edited record From 5f71843e2c6afd111b57fee3d8e7a52f7033b344 Mon Sep 17 00:00:00 2001 From: pvdk Date: Tue, 18 Mar 2014 00:00:13 +0100 Subject: [PATCH 064/127] Updated credits.txt --- credits.txt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/credits.txt b/credits.txt index 6012557638..28a30e907e 100644 --- a/credits.txt +++ b/credits.txt @@ -82,12 +82,14 @@ Sandy Carter (bwrsandman) - Arch Linux Public Relations and Translations: +Alex McKibben (WeirdSexy) - Podcaster Artem Kotsynyak (greye) - Russian News Writer +Jim Clauwaert (Zedd) - Public Outreach Julien Voisin (jvoisin/ap0) - French News Writer +Lukasz Gromanowski (lgro) - English News Writer Mickey Lyle (raevol) - Release Manager Pithorn - Chinese News Writer -sir_herrbatka - English/Polish News Writer -Alex McKibben (WeirdSexy) - Podcaster +sir_herrbatka - Polish News Writer Website: From db774b02d75116b60e5116b3553be0391cb908e4 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 18 Mar 2014 09:36:22 +0100 Subject: [PATCH 065/127] clone and create buttons work --- apps/opencs/view/world/dialoguesubview.cpp | 38 ++++++++++-- apps/opencs/view/world/dialoguesubview.hpp | 12 +++- apps/opencs/view/world/subviews.cpp | 72 ++++++++++++++++------ 3 files changed, 99 insertions(+), 23 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 6bd8001c7a..1692cdf80b 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -31,6 +31,7 @@ #include "recordstatusdelegate.hpp" #include "util.hpp" +#include "tablebottombox.hpp" /* ==============================NotEditableSubDelegate========================================== */ @@ -379,7 +380,7 @@ void CSVWorld::EditWidget::remake(int row) */ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, - bool createAndDelete) : + const CreatorFactoryBase& creatorFactory, bool sorting) : SubView (id), mEditWidget(0), @@ -416,7 +417,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM 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()), this, SLOT(revertRecord())); connect(deleteButton, SIGNAL(clicked()), this, SLOT(deleteRecord())); @@ -428,7 +429,21 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mMainLayout->addLayout(buttonsLayout); mMainLayout->addWidget(mEditWidget); - mEditWidget->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Ignored); + mEditWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); + + mMainLayout->addWidget (mBottom = + new TableBottomBox (creatorFactory, document.getData(), document.getUndoStack(), id, this)); + + mBottom->setSizePolicy(QSizePolicy::Ignored, QSizePolicy::Fixed); + connect(mBottom, SIGNAL(requestFocus(const std::string&)), this, SLOT(requestFocus(const std::string&))); + connect(addButton, SIGNAL(clicked()), mBottom, SLOT(createRequest())); + + if(!mBottom->canCreateAndDelete()) + { + cloneButton->setDisabled(true); + addButton->setDisabled(true); + deleteButton->setDisabled(true); + } dataChanged(mTable->index(mRow, 0)); setWidget(mainWidget); @@ -567,7 +582,10 @@ void CSVWorld::DialogueSubView::revertRecord() void CSVWorld::DialogueSubView::deleteRecord() { int rows = mTable->rowCount(); - if (!mLocked && mTable->columnCount() > 0 && mRow < mTable->rowCount() ) + if (!mLocked && + mTable->columnCount() > 0 && + mRow < mTable->rowCount() && + mBottom->canCreateAndDelete()) { mUndoStack.push(new CSMWorld::DeleteCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toStdString())); if (rows != mTable->rowCount()) @@ -585,4 +603,16 @@ void CSVWorld::DialogueSubView::deleteRecord() } } } +} + +void CSVWorld::DialogueSubView::requestFocus (const std::string& id) +{ + mRow = mTable->getModelIndex (id, 0).row(); + mEditWidget->remake(mRow); +} + +void CSVWorld::DialogueSubView::cloneRequest () +{ + mBottom->cloneRequest(mTable->data(mTable->index (mRow, 0)).toString().toStdString(), + static_cast(mTable->data(mTable->index(mRow, 2)).toInt())); } \ No newline at end of file diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index bf6e70e0d3..af07d28f4c 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -29,6 +29,8 @@ namespace CSMDoc namespace CSVWorld { class CommandDelegate; + class CreatorFactoryBase; + class TableBottomBox; class NotEditableSubDelegate : public QAbstractItemDelegate { @@ -166,10 +168,14 @@ namespace CSVWorld int mRow; bool mLocked; const CSMDoc::Document& mDocument; + TableBottomBox* mBottom; public: - DialogueSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document, bool createAndDelete = false); + DialogueSubView (const CSMWorld::UniversalId& id, + CSMDoc::Document& document, + const CreatorFactoryBase& creatorFactory, + bool sorting = false); virtual void setEditLock (bool locked); @@ -182,12 +188,16 @@ namespace CSVWorld void revertRecord(); void deleteRecord(); + void cloneRequest(); + void dataChanged(const QModelIndex & index); ///\brief we need to care for deleting currently edited record void tableMimeDataDropped(QWidget* editor, const QModelIndex& index, const CSMWorld::UniversalId& id, const CSMDoc::Document* document); + + void requestFocus (const std::string& id); }; } diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index d4d9565a4a..f647a9261f 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -79,22 +79,58 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) manager.add (CSMWorld::UniversalId::Type_Scene, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_Region, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_Spell, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_Referenceable, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_Birthsign, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_Global, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_Gmst, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_Race, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_Class, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_Reference, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_Cell, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_Filter, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_Sound, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_Faction, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_Skill, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_JournalInfo, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_TopicInfo, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_Topic, new CSVDoc::SubViewFactory); - manager.add(CSMWorld::UniversalId::Type_Journal, new CSVDoc::SubViewFactory); + //edit subviews + manager.add (CSMWorld::UniversalId::Type_Region, + new CSVDoc::SubViewFactoryWithCreator > (false)); + + manager.add (CSMWorld::UniversalId::Type_Spell, + new CSVDoc::SubViewFactoryWithCreator > (false)); + + manager.add (CSMWorld::UniversalId::Type_Referenceable, + new CSVDoc::SubViewFactoryWithCreator > (false)); + + manager.add (CSMWorld::UniversalId::Type_Birthsign, + new CSVDoc::SubViewFactoryWithCreator > (false)); + + manager.add (CSMWorld::UniversalId::Type_Global, + new CSVDoc::SubViewFactoryWithCreator > (false)); + + manager.add (CSMWorld::UniversalId::Type_Gmst, + new CSVDoc::SubViewFactoryWithCreator > (false)); + + manager.add (CSMWorld::UniversalId::Type_Race, + new CSVDoc::SubViewFactoryWithCreator > (false)); + + manager.add (CSMWorld::UniversalId::Type_Class, + new CSVDoc::SubViewFactoryWithCreator > (false)); + + manager.add (CSMWorld::UniversalId::Type_Reference, + new CSVDoc::SubViewFactoryWithCreator > (false)); + + manager.add (CSMWorld::UniversalId::Type_Cell, + new CSVDoc::SubViewFactoryWithCreator > (false)); + + manager.add (CSMWorld::UniversalId::Type_Filter, + new CSVDoc::SubViewFactoryWithCreator > (false)); + + manager.add (CSMWorld::UniversalId::Type_Sound, + new CSVDoc::SubViewFactoryWithCreator > (false)); + + manager.add (CSMWorld::UniversalId::Type_Faction, + new CSVDoc::SubViewFactoryWithCreator > (false)); + + manager.add (CSMWorld::UniversalId::Type_Skill, + new CSVDoc::SubViewFactoryWithCreator > (false)); + + manager.add (CSMWorld::UniversalId::Type_JournalInfo, + new CSVDoc::SubViewFactoryWithCreator > (false)); + + manager.add (CSMWorld::UniversalId::Type_TopicInfo, + new CSVDoc::SubViewFactoryWithCreator > (false)); + + manager.add (CSMWorld::UniversalId::Type_Topic, + new CSVDoc::SubViewFactoryWithCreator > (false)); + + manager.add (CSMWorld::UniversalId::Type_Journal, + new CSVDoc::SubViewFactoryWithCreator > (false)); } \ No newline at end of file From c0b2b783cb5cb235c5c0b575e656c2ae008aba50 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 18 Mar 2014 20:53:21 +0100 Subject: [PATCH 066/127] use more proper creators --- apps/opencs/view/world/subviews.cpp | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index f647a9261f..6c832e179d 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -87,7 +87,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) new CSVDoc::SubViewFactoryWithCreator > (false)); manager.add (CSMWorld::UniversalId::Type_Referenceable, - new CSVDoc::SubViewFactoryWithCreator > (false)); + new CSVDoc::SubViewFactoryWithCreator > (false)); manager.add (CSMWorld::UniversalId::Type_Birthsign, new CSVDoc::SubViewFactoryWithCreator > (false)); @@ -108,7 +108,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) new CSVDoc::SubViewFactoryWithCreator > (false)); manager.add (CSMWorld::UniversalId::Type_Cell, - new CSVDoc::SubViewFactoryWithCreator > (false)); + new CSVDoc::SubViewFactoryWithCreator > (false)); manager.add (CSMWorld::UniversalId::Type_Filter, new CSVDoc::SubViewFactoryWithCreator > (false)); @@ -123,14 +123,14 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) new CSVDoc::SubViewFactoryWithCreator > (false)); manager.add (CSMWorld::UniversalId::Type_JournalInfo, - new CSVDoc::SubViewFactoryWithCreator > (false)); + new CSVDoc::SubViewFactoryWithCreator > (false)); manager.add (CSMWorld::UniversalId::Type_TopicInfo, - new CSVDoc::SubViewFactoryWithCreator > (false)); + new CSVDoc::SubViewFactoryWithCreator(false)); manager.add (CSMWorld::UniversalId::Type_Topic, new CSVDoc::SubViewFactoryWithCreator > (false)); manager.add (CSMWorld::UniversalId::Type_Journal, - new CSVDoc::SubViewFactoryWithCreator > (false)); + new CSVDoc::SubViewFactoryWithCreator (false)); } \ No newline at end of file From 010160d04793616eacc294eb9e821101609ef128 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Tue, 18 Mar 2014 20:56:55 +0100 Subject: [PATCH 067/127] missed those :/ --- apps/opencs/view/world/subviews.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 6c832e179d..116f1997b7 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -105,7 +105,7 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) new CSVDoc::SubViewFactoryWithCreator > (false)); manager.add (CSMWorld::UniversalId::Type_Reference, - new CSVDoc::SubViewFactoryWithCreator > (false)); + new CSVDoc::SubViewFactoryWithCreator > (false)); manager.add (CSMWorld::UniversalId::Type_Cell, new CSVDoc::SubViewFactoryWithCreator > (false)); @@ -126,10 +126,10 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) new CSVDoc::SubViewFactoryWithCreator > (false)); manager.add (CSMWorld::UniversalId::Type_TopicInfo, - new CSVDoc::SubViewFactoryWithCreator(false)); + new CSVDoc::SubViewFactoryWithCreator >(false)); manager.add (CSMWorld::UniversalId::Type_Topic, - new CSVDoc::SubViewFactoryWithCreator > (false)); + new CSVDoc::SubViewFactoryWithCreator (false)); manager.add (CSMWorld::UniversalId::Type_Journal, new CSVDoc::SubViewFactoryWithCreator (false)); From 8f3103ce655d5089396fbaeb94c3c1c924115961 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 19 Mar 2014 11:42:43 +0100 Subject: [PATCH 068/127] added preview button --- apps/opencs/view/world/dialoguesubview.cpp | 13 +++++++++++++ apps/opencs/view/world/dialoguesubview.hpp | 3 +++ apps/opencs/view/world/table.cpp | 1 + 3 files changed, 17 insertions(+) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 1692cdf80b..9f86a8ce38 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -405,16 +405,21 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM buttonsLayout->addWidget(nextButton, 1); buttonsLayout->addStretch(2); + QToolButton* previewButton = new QToolButton(mainWidget); QToolButton* cloneButton = new QToolButton(mainWidget); QToolButton* addButton = new QToolButton(mainWidget); QToolButton* deleteButton = new QToolButton(mainWidget); QToolButton* revertButton = new QToolButton(mainWidget); + previewButton->setEnabled(mTable->hasPreview()); + + buttonsLayout->addWidget(previewButton); buttonsLayout->addWidget(cloneButton); buttonsLayout->addWidget(addButton); buttonsLayout->addWidget(deleteButton); buttonsLayout->addWidget(revertButton); + connect(previewButton, SIGNAL(clicked()), this, SLOT(showPreview())); connect(nextButton, SIGNAL(clicked()), this, SLOT(nextId())); connect(prevButton, SIGNAL(clicked()), this, SLOT(prevId())); connect(cloneButton, SIGNAL(clicked()), this, SLOT(cloneRequest())); @@ -615,4 +620,12 @@ void CSVWorld::DialogueSubView::cloneRequest () { mBottom->cloneRequest(mTable->data(mTable->index (mRow, 0)).toString().toStdString(), static_cast(mTable->data(mTable->index(mRow, 2)).toInt())); +} + +void CSVWorld::DialogueSubView::showPreview () +{ + if (mTable->hasPreview()) + { + emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, mTable->data(mTable->index (mRow, 0)).toString().toStdString()), ""); + } } \ No newline at end of file diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index af07d28f4c..8a96e3ec0d 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -185,7 +185,10 @@ namespace CSVWorld void prevId(); + void showPreview(); + void revertRecord(); + void deleteRecord(); void cloneRequest(); diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index 4ce18ce68e..cd9138c357 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -442,6 +442,7 @@ void CSVWorld::Table::previewRecord() emit editRequest (CSMWorld::UniversalId (CSMWorld::UniversalId::Type_Preview, id) , ""); } } + void CSVWorld::Table::updateEditorSetting (const QString &settingName, const QString &settingValue) { int columns = mModel->columnCount(); From ea9b6fa37e265ac7b896f204f42fa321f962b14f Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Wed, 19 Mar 2014 12:01:36 +0100 Subject: [PATCH 069/127] view button --- apps/opencs/view/world/dialoguesubview.cpp | 30 ++++++++++++++++++---- apps/opencs/view/world/dialoguesubview.hpp | 2 ++ 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 9f86a8ce38..53e53e0e67 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -405,21 +405,30 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM buttonsLayout->addWidget(nextButton, 1); buttonsLayout->addStretch(2); - QToolButton* previewButton = new QToolButton(mainWidget); QToolButton* cloneButton = new QToolButton(mainWidget); QToolButton* addButton = new QToolButton(mainWidget); QToolButton* deleteButton = new QToolButton(mainWidget); QToolButton* revertButton = new QToolButton(mainWidget); - previewButton->setEnabled(mTable->hasPreview()); + if (mTable->hasPreview()) + { + QToolButton* previewButton = new QToolButton(mainWidget); + buttonsLayout->addWidget(previewButton); + connect(previewButton, SIGNAL(clicked()), this, SLOT(showPreview())); + } + + if (mTable->getViewing()!=CSMWorld::IdTable::Viewing_None) + { + QToolButton* viewButton = new QToolButton(mainWidget); + buttonsLayout->addWidget(viewButton); + connect(viewButton, SIGNAL(clicked()), this, SLOT(viewRecord())); + } - buttonsLayout->addWidget(previewButton); buttonsLayout->addWidget(cloneButton); buttonsLayout->addWidget(addButton); buttonsLayout->addWidget(deleteButton); buttonsLayout->addWidget(revertButton); - connect(previewButton, SIGNAL(clicked()), this, SLOT(showPreview())); connect(nextButton, SIGNAL(clicked()), this, SLOT(nextId())); connect(prevButton, SIGNAL(clicked()), this, SLOT(prevId())); connect(cloneButton, SIGNAL(clicked()), this, SLOT(cloneRequest())); @@ -624,8 +633,19 @@ void CSVWorld::DialogueSubView::cloneRequest () void CSVWorld::DialogueSubView::showPreview () { - if (mTable->hasPreview()) + if (mTable->hasPreview() && mRow < mTable->rowCount()) { emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, mTable->data(mTable->index (mRow, 0)).toString().toStdString()), ""); } +} + +void CSVWorld::DialogueSubView::viewRecord() +{ + if (mRow < mTable->rowCount()) + { + std::pair params = mTable->view (mRow); + + if (params.first.getType()!=CSMWorld::UniversalId::Type_None) + emit focusId (params.first, params.second); + } } \ No newline at end of file diff --git a/apps/opencs/view/world/dialoguesubview.hpp b/apps/opencs/view/world/dialoguesubview.hpp index 8a96e3ec0d..5642f46a0b 100644 --- a/apps/opencs/view/world/dialoguesubview.hpp +++ b/apps/opencs/view/world/dialoguesubview.hpp @@ -187,6 +187,8 @@ namespace CSVWorld void showPreview(); + void viewRecord(); + void revertRecord(); void deleteRecord(); From 7ed3effc92ef92b945cc980983a53b56103da47e Mon Sep 17 00:00:00 2001 From: "Alexander \"Ace\" Olofsson" Date: Wed, 19 Mar 2014 12:01:53 +0100 Subject: [PATCH 070/127] Fix windows packaging issue now that the OFL license doesn't exist anymore. --- CMakeLists.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 154f30161b..fb3827588b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -465,7 +465,6 @@ if(WIN32) INSTALL(FILES "${OpenMW_SOURCE_DIR}/readme.txt" "${OpenMW_SOURCE_DIR}/GPL3.txt" - "${OpenMW_SOURCE_DIR}/OFL.txt" "${OpenMW_SOURCE_DIR}/DejaVu Font License.txt" "${OpenMW_BINARY_DIR}/settings-default.cfg" "${OpenMW_BINARY_DIR}/transparency-overrides.cfg" From e4c4747a27b9597cfb3c9489cbd74e9fc9fd3d76 Mon Sep 17 00:00:00 2001 From: Rohit Nirmal Date: Wed, 19 Mar 2014 20:08:01 -0500 Subject: [PATCH 071/127] Play item sound even if merchant doesn't purchase it. --- apps/openmw/mwgui/inventorywindow.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 5fa1d3bb16..16ddab584a 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -162,6 +162,7 @@ namespace MWGui } const ItemStack& item = mTradeModel->getItem(index); + std::string sound = MWWorld::Class::get(item.mBase).getDownSoundId(item.mBase); MWWorld::Ptr object = item.mBase; int count = item.mCount; @@ -213,6 +214,7 @@ namespace MWGui int services = MWBase::Environment::get().getWindowManager()->getTradeWindow()->getMerchantServices(); if (!MWWorld::Class::get(object).canSell(object, services)) { + MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0); MWBase::Environment::get().getWindowManager()-> messageBox("#{sBarterDialog4}"); return; From 1acd1bd913c8dc68483c8ce82c0a55678fd13219 Mon Sep 17 00:00:00 2001 From: slothlife Date: Thu, 20 Mar 2014 01:25:52 -0500 Subject: [PATCH 072/127] Feature #1173: Saved Game: include weather state Removed some unused state in and changed Ogre::String to std::string in WeatherManager. --- apps/openmw/mwstate/statemanagerimp.cpp | 1 + apps/openmw/mwworld/weather.cpp | 77 ++++++++++++++++++++++--- apps/openmw/mwworld/weather.hpp | 37 +++++++----- apps/openmw/mwworld/worldimp.cpp | 4 +- components/esm/defs.hpp | 1 + 5 files changed, 93 insertions(+), 27 deletions(-) diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index d6309c1c9f..c0860b7849 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -266,6 +266,7 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl case ESM::REC_GLOB: case ESM::REC_PLAY: case ESM::REC_CSTA: + case ESM::REC_WTHR: MWBase::Environment::get().getWorld()->readRecord (reader, n.val, contentFileMap); break; diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index 5f38ee2863..b74ca63935 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -1,5 +1,8 @@ #include "weather.hpp" +#include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" #include "../mwbase/soundmanager.hpp" @@ -15,6 +18,15 @@ using namespace Ogre; using namespace MWWorld; using namespace MWSound; +#define HOUR "HOUR" +#define WINDSPEED "WNSP" +#define CURRENTWEATHER "CWTH" +#define NEXTWEATHER "NWTH" +#define CURRENTREGION "CREG" +#define FIRSTUPDATE "FUPD" +#define REMAININGTRANSITIONTIME "RTTM" +#define TIMEPASSED "TMPS" + namespace { float lerp (float x, float y, float factor) @@ -91,8 +103,7 @@ WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fa mHour(14), mCurrentWeather("clear"), mNextWeather(""), mFirstUpdate(true), mWeatherUpdateTime(0), mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0), mRemainingTransitionTime(0), - mMonth(0), mDay(0), mTimePassed(0), mFallback(fallback), mWindSpeed(0.f), - mRendering(rendering) + mTimePassed(0), mFallback(fallback), mWindSpeed(0.f), mRendering(rendering) { //Globals mThunderSoundID0 = mFallback->getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_0"); @@ -530,7 +541,7 @@ void WeatherManager::stopSounds(bool stopAll) } } -Ogre::String WeatherManager::nextWeather(const ESM::Region* region) const +std::string WeatherManager::nextWeather(const ESM::Region* region) const { std::vector probability; @@ -599,12 +610,6 @@ void WeatherManager::setHour(const float hour) mHour = hour; } -void WeatherManager::setDate(const int day, const int month) -{ - mDay = day; - mMonth = month; -} - unsigned int WeatherManager::getWeatherID() const { // Source: http://www.uesp.net/wiki/Tes3Mod:GetCurrentWeather @@ -691,6 +696,60 @@ bool WeatherManager::isDark() const return exterior && (mHour < mSunriseTime || mHour > mNightStart - 1); } +void WeatherManager::write(ESM::ESMWriter& writer) +{ + writer.startRecord(ESM::REC_WTHR); + writer.writeHNT(HOUR, mHour); + writer.writeHNT(WINDSPEED, mWindSpeed); + writer.writeHNCString(CURRENTWEATHER, mCurrentWeather.c_str()); + writer.writeHNCString(NEXTWEATHER, mNextWeather.c_str()); + writer.writeHNCString(CURRENTREGION, mCurrentRegion.c_str()); + writer.writeHNT(FIRSTUPDATE, mFirstUpdate); + writer.writeHNT(REMAININGTRANSITIONTIME, mRemainingTransitionTime); + writer.writeHNT(TIMEPASSED, mTimePassed); + writer.endRecord(ESM::REC_WTHR); +} + +bool WeatherManager::readRecord(ESM::ESMReader& reader, int32_t type) +{ + if(ESM::REC_WTHR == type) + { + // store state in locals so that if we fail to load, we don't leave the manager in a half-way state + float newHour = 0.0; + reader.getHNT(newHour, HOUR); + float newWindSpeed = 0.0; + reader.getHNT(newWindSpeed, WINDSPEED); + std::string newCurrentWeather = reader.getHNString(CURRENTWEATHER); + std::string newNextWeather = reader.getHNString(NEXTWEATHER); + std::string newCurrentRegion = reader.getHNString(CURRENTREGION); + bool newFirstUpdate = false; + reader.getHNT(newFirstUpdate, FIRSTUPDATE); + float newRemainingTransitionTime = 0.0; + reader.getHNT(newRemainingTransitionTime, REMAININGTRANSITIONTIME); + double newTimePassed = 0.0; + reader.getHNT(newTimePassed, TIMEPASSED); + + // reset other temporary state + mRegionOverrides.clear(); + stopSounds(true); // TODO: inconsistent state if this throws... + mRegionMods.clear(); + + // swap in new values, now that we can't fail + mHour = newHour; + mWindSpeed = newWindSpeed; + mCurrentWeather.swap(newCurrentWeather); + mNextWeather.swap(newNextWeather); + mCurrentRegion.swap(newCurrentRegion); + mFirstUpdate = newFirstUpdate; + mRemainingTransitionTime = newRemainingTransitionTime; + mTimePassed = newTimePassed; + + return true; + } + + return false; +} + void WeatherManager::switchToNextWeather(bool instantly) { MWBase::World* world = MWBase::Environment::get().getWorld(); diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index fa2d9bd8e1..3167a64c2a 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -1,12 +1,16 @@ #ifndef GAME_MWWORLD_WEATHER_H #define GAME_MWWORLD_WEATHER_H -#include +#include +#include + #include namespace ESM { struct Region; + class ESMWriter; + class ESMReader; } namespace MWRender @@ -21,8 +25,8 @@ namespace MWWorld /// Defines the actual weather that results from weather setting (see below), time of day and weather transition struct WeatherResult { - Ogre::String mCloudTexture; - Ogre::String mNextCloudTexture; + std::string mCloudTexture; + std::string mNextCloudTexture; float mCloudBlendFactor; Ogre::ColourValue mFogColor; @@ -48,14 +52,14 @@ namespace MWWorld bool mNight; // use night skybox float mNightFade; // fading factor for night skybox - Ogre::String mAmbientLoopSoundID; + std::string mAmbientLoopSoundID; }; /// Defines a single weather setting (according to INI) struct Weather { - Ogre::String mCloudTexture; + std::string mCloudTexture; // Sky (atmosphere) colors Ogre::ColourValue mSkySunriseColor, @@ -105,10 +109,10 @@ namespace MWWorld // Sound effect // This is used for Blight, Ashstorm and Blizzard (Bloodmoon) - Ogre::String mAmbientLoopSoundID; + std::string mAmbientLoopSoundID; // Rain sound effect - Ogre::String mRainLoopSoundID; + std::string mRainLoopSoundID; /// \todo disease chance }; @@ -142,8 +146,6 @@ namespace MWWorld float getWindSpeed() const; - void setDate(const int day, const int month); - void advanceTime(double hours) { mTimePassed += hours*3600; @@ -156,22 +158,25 @@ namespace MWWorld /// @see World::isDark bool isDark() const; + void write(ESM::ESMWriter& writer); + + bool readRecord(ESM::ESMReader& reader, int32_t type); + private: float mHour; - int mDay, mMonth; float mWindSpeed; MWWorld::Fallback* mFallback; void setFallbackWeather(Weather& weather,const std::string& name); MWRender::RenderingManager* mRendering; - std::map mWeatherSettings; + std::map mWeatherSettings; std::map mRegionOverrides; std::vector mSoundsPlaying; - Ogre::String mCurrentWeather; - Ogre::String mNextWeather; + std::string mCurrentWeather; + std::string mNextWeather; std::string mCurrentRegion; @@ -186,13 +191,13 @@ namespace MWWorld double mTimePassed; // time passed since last update void transition(const float factor); - void setResult(const Ogre::String& weatherType); + void setResult(const std::string& weatherType); float calculateHourFade (const std::string& moonName) const; float calculateAngleFade (const std::string& moonName, float angle) const; - void setWeather(const Ogre::String& weatherType, bool instant=false); - Ogre::String nextWeather(const ESM::Region* region) const; + void setWeather(const std::string& weatherType, bool instant=false); + std::string nextWeather(const ESM::Region* region) const; WeatherResult mResult; typedef std::map > RegionModMap; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 62bdd38ea1..81afc394a6 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -279,6 +279,7 @@ namespace MWWorld mGlobalVariables.write (writer); mCells.write (writer); mPlayer->write (writer); + mWeatherManager->write (writer); } void World::readRecord (ESM::ESMReader& reader, int32_t type, @@ -287,6 +288,7 @@ namespace MWWorld if (!mStore.readRecord (reader, type) && !mGlobalVariables.readRecord (reader, type) && !mPlayer->readRecord (reader, type) && + !mWeatherManager->readRecord (reader, type) && !mCells.readRecord (reader, type, contentFileMap)) { throw std::runtime_error ("unknown record in saved game"); @@ -680,8 +682,6 @@ namespace MWWorld mGlobalVariables["month"].setInteger (month); mRendering->skySetDate (day, month); - - mWeatherManager->setDate (day, month); } void World::setMonth (int month) diff --git a/components/esm/defs.hpp b/components/esm/defs.hpp index 57842796f5..4d5b36c740 100644 --- a/components/esm/defs.hpp +++ b/components/esm/defs.hpp @@ -92,6 +92,7 @@ enum RecNameInts REC_CSTA = 0x41545343, REC_GMAP = 0x50414d47, REC_DIAS = 0x53414944, + REC_WTHR = 0x52485457, // format 1 REC_FILT = 0x544C4946 From ad2f9a69a1aaf2abd4a42d170cec472f1cf9feba Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 20 Mar 2014 08:59:04 +0100 Subject: [PATCH 073/127] prevent deleting already deleted record --- apps/opencs/view/world/dialoguesubview.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 53e53e0e67..5c718ad7f8 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -596,9 +596,15 @@ void CSVWorld::DialogueSubView::revertRecord() void CSVWorld::DialogueSubView::deleteRecord() { int rows = mTable->rowCount(); + + //easier than disabling the button + CSMWorld::RecordBase::State state = static_cast(mTable->data (mTable->index (mRow, 1)).toInt()); + bool deledetedOrErased = (state == CSMWorld::RecordBase::State_Deleted || state == CSMWorld::RecordBase::State_Erased); + if (!mLocked && mTable->columnCount() > 0 && - mRow < mTable->rowCount() && + !deledetedOrErased && + mRow < rows && mBottom->canCreateAndDelete()) { mUndoStack.push(new CSMWorld::DeleteCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toStdString())); From 5c34823bb077ac4ffaeb947d345a2169b4114c90 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 20 Mar 2014 13:59:00 +0100 Subject: [PATCH 074/127] added some placeholder icons --- apps/opencs/view/world/dialoguesubview.cpp | 6 ++++++ files/opencs/add.png | Bin 0 -> 520 bytes files/opencs/edit-clone.png | Bin 0 -> 472 bytes files/opencs/edit-delete.png | Bin 0 -> 680 bytes files/opencs/edit-preview.png | Bin 0 -> 525 bytes files/opencs/edit-undo.png | Bin 0 -> 650 bytes files/opencs/go-next.png | Bin 930 -> 676 bytes files/opencs/go-previous.png | Bin 955 -> 655 bytes files/opencs/resources.qrc | 5 +++++ 9 files changed, 11 insertions(+) create mode 100644 files/opencs/add.png create mode 100644 files/opencs/edit-clone.png create mode 100644 files/opencs/edit-delete.png create mode 100644 files/opencs/edit-preview.png create mode 100644 files/opencs/edit-undo.png diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 5c718ad7f8..4962acfce6 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -406,13 +406,18 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM buttonsLayout->addStretch(2); QToolButton* cloneButton = new QToolButton(mainWidget); + cloneButton->setIcon(QIcon(":/edit-clone.png")); QToolButton* addButton = new QToolButton(mainWidget); + addButton->setIcon(QIcon(":/add.png")); QToolButton* deleteButton = new QToolButton(mainWidget); + deleteButton->setIcon(QIcon(":/edit-delete.png")); QToolButton* revertButton = new QToolButton(mainWidget); + revertButton->setIcon(QIcon(":/edit-undo.png")); if (mTable->hasPreview()) { QToolButton* previewButton = new QToolButton(mainWidget); + previewButton->setIcon(QIcon(":/edit-preview.png")); buttonsLayout->addWidget(previewButton); connect(previewButton, SIGNAL(clicked()), this, SLOT(showPreview())); } @@ -420,6 +425,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM if (mTable->getViewing()!=CSMWorld::IdTable::Viewing_None) { QToolButton* viewButton = new QToolButton(mainWidget); + viewButton->setIcon(QIcon(":/cell.png")); buttonsLayout->addWidget(viewButton); connect(viewButton, SIGNAL(clicked()), this, SLOT(viewRecord())); } diff --git a/files/opencs/add.png b/files/opencs/add.png new file mode 100644 index 0000000000000000000000000000000000000000..3f1347e2452820b6687dc1128f6e9e8d9f2ef827 GIT binary patch literal 520 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`EX7WqAsj$Z!;#Vf2?p zUk71ECym(^Ktah8*NBqf{Irtt#G+J&^73-M%)IR4Bl#B&opTdp z4dzN(xKt@=ZBuK4^6eIr=!mY~Z(P&F>KZg8SQK47IP4Z}Q&aoFvAg>HxriT1Cq$i> zNzE{BFMg&tL-KCRn^n>cn?#MW+bwgG_!)#weLP?GY_qIpN6DL9ot~9ncLs{SKy>c|Kn;tJhp&ZSDqn*2mhvEt5|uD;+)KvAc7@PoW)K)3}>7 zB%zi?r<_YaegC>6EtPzOSmRfMHzpLaUS0 zZ5iIOxMiEfImLv%W90DAR9MhiljuO*(b|p7p1FMbhW2n*Y09zyE_Tsb;OjL!;ZExMuKl^>bP0 Hl+XkK6MoQ? literal 0 HcmV?d00001 diff --git a/files/opencs/edit-clone.png b/files/opencs/edit-clone.png new file mode 100644 index 0000000000000000000000000000000000000000..3398e8d18265c6944d605cd3fbb6c6b02597119e GIT binary patch literal 472 zcmV;}0Vn>6P)ZSXqf8r_B|Y z&f3OC(MALdv9OU;Hlm!RSXgNzB!ytW(%9UQTogI=ZQkxnVvz(l$*yLanK$pBpP7H& zGx{gjE3{$R<0Zo{F96mSXWlGc-uxYSC+flF?Xxdn_*?gzQs zvpNSrNjns7GCUUk02K_=q$|=#@4$CL9bo_#R`y#708TRx^xD^q4SgXtKMjD^np7&q z*=3r%HORzJ#J_{Ob?SSf(OHtoBvMK&%Oa6TkWQx?aArMd7R#iJ5CSPB*^e=7+r}_j zH)%ABv$Hyfy820vI!C!sRA8%`cdD`7J<7<`K~)3q1F4hssB^}DT|oISCHD^P6mZ=f zZZU^^x@UL$bz6ZNK#0oI7FzwsQI9xI)zcBD?CII`D|IzMIheaat3U$X7J=^wx&%}d zSU(7b{vkvj!Vef9B=XsQpTPJWXKy3kpng$7sW#Q8uhCbmx3Jx>?X?$ht)1;%?%O#4 O0000&~9SKOY%f0nX^lS0%q#YP1;Cv`C~wifvVWH7q5i>VkBIIeP6 z?s|6)au-91QGBQO`{sE*@B4fS?A7A^!aG@(#_<=$akkoxxl9xQXmcpb()eup8Wcsb zgoa^snGM6hljX9thz?EX=KSV+MNuFK0-`7)n@QnL;d#!A@UhW?AP8tQ8h?ynYKO=6BACOv97OzXrAtf@ z2O)x1X8|H-V>nD%fY=%S{{Wx9i2r094LW{B44uo@Kw#`p>kX`0Uo?09s&V;JTzyn7 zDU*{^%-Y&}CK{d4s?`b^i%n^@T9ulJ#`L$9H{{~N1F9)O#I0o&NqHSeDc6cDqz8 zK1}bwAaOHui(g)OtONMGwY4emZr<;5I_X`d&8)9~I0*nN&z?HdsoA#LQO@rNluJuR z`2EL^Bopb;WFp!lvI6;RN#5=* z4F5rJ!QSPQfg+p*9+AZi4BWyX%*Zfnjs#GUy~NYkmHies6E_bB&t#W1Kp~G3*N775 z{M_8syb=bDWK9Jl0|PS!uf*)qB!%FT)XcopA}+4vqSVBa)D(sC%#sX+l8jUZcTe8{ z1uH9sjFOT9D}DX+%-jOK{GxQ_{}B!h42));E{-7CVLZPN@n~aG&Ys+HJt9Jx+odjH(FI|Z8R`B=8%G_}@Q?qi} zKSsxRi-PkzzyG#uuYPdeyHfb}Mz%)F1QCP%^3RQ0XYXU^k7Ryo$Gdo^&%$@QJQe41 zi#^Ta`>{e!`ZSm9`+4vr?gKS2DO*2^U{>lFJfR}s(W{*@X*2x@gv+C>cX=# z)-ukRE0G!RbKd9EN6n12ANze7uk2#DSyK1+%bq5~wi~aM4({+Z$YZ`xRe99hrp2(W z?YEEFT>a9&eH|_?OOmXo?Z^uj+t!zIc-NGzbB!-{GOvug-}N>^N$I$f(7T;(f}Tv? z)xUS&-WxW-_qjiVyJqQq;Sa`~6BuXRSC#+3x20iG(5i#`t-i1_bQNB&`VuoA7%L2( Lu6{1-oD!M<@FT~7 literal 0 HcmV?d00001 diff --git a/files/opencs/edit-undo.png b/files/opencs/edit-undo.png new file mode 100644 index 0000000000000000000000000000000000000000..8b0fef9a8319452009247864c41e033694859278 GIT binary patch literal 650 zcmV;50(Jd~P)kSC&LBJ zfVRcM$?V1P3B6PcAX~#mZX7Dr0E-up6>u&Ai1M4+$6px*d6g)50zul{6fOZfD5 zx^(<(+NuITAZTdtF*`7sbB~Mx0Ae$D>fg&k;5u>{h0Ft(%sL2>YF!TkK|`BOGW-0q z$<55rD9F$#2!Mm7ygZedyZydz;2gN<0Fly!zty-=mBaVpcsEVu>hcW{d1#Z{npnGY zBY*fjmK0%?8^t(;YR@+XG=oH^Fxc%lEVS$r0NiT$nf{@pT|4*Ae2zV-96O_3`)`13 k>$j#pJbyuT?P=Bf1qBx3B`dxp6aWAK07*qoM6N<$g68)pi~s-t literal 0 HcmV?d00001 diff --git a/files/opencs/go-next.png b/files/opencs/go-next.png index 6f3f65d33d303315f0d8d9dd03c7e7e2427d4950..6ef8de76e0f5bf01c09da24a07c61cfe558d7a4b 100644 GIT binary patch delta 634 zcmV-=0)_pe2c!idiBL{Q4GJ0x0000DNk~Le0000G0000G2nGNE03Y-JVUZy>e*!j1 zL_t(Ijg^v1NK|1Q#ed)9&cjB-6jH=qL?CDs1clQ^Xwf2q1Y1UdLb%Ctj5b0mH;s^s zC~^}Ny`)8AK5!8&X3#056gSZ#EHj<4fga;{@7(*f2wyW3)Pb}4{)fZ)pZ|w3hJ1#* zbgZ#cw-uY^Q&I%Rqj7ijfxd8;e>D(}SfOH?H54@fxYE)aJbCo&X#}(3h}H1l21;t0 z4xjP0H(##}`a=`ph}Bk1CmJLAD~6q09u?V}?Sp}-&tp`T?ZYRx@p$~!%7^)xVPiNS zi#k6y3_7*xxp*Hb6iO(BkO%|-iBCg#xRm*Ku&cbD`1H6lHaW0>F{ffte`f|j1Grv} z*vDrmsZm0K5C{Q60m5V1o+G_9&%wGQR!!BO+NWc8C&Ce{BNlb~H9*c=C7oHocC*-S z7Ns<$C1sQZLijB|M!48sj(1C=)P(9pYjao0(5pv%$FEw)G{Dl2Io>BSu?9kCluf4;V$ zgEcrgo5WONb$WJc(c2WcptHXvs3@<@eEXgnHZB)7NB*Y-LK0t2r|!j~g^}~|8$sR) Uv~G6gwg3PC07*qoM6N<$f}Qpxc>n+a delta 890 zcmV-=1BLvg1)>KbiBL{Q4GJ0x0000DNk~Le0000M0000M2nGNE0K~LxJCPwbe*-j0 zL_t(IjkT3qXdP7)hQBql=j3ATMJXvL)+cZ6gM|t;iO_;p1VKfu`XW-L6ntq(NehCa zU{Rz#^hHohY0N{2S_&y*OEiWirYf2iH8jRc)TFV-1k;n`%w^ABKAbsqk~YzYbivQe zhBe>X|JsY$qN-et@U9B=|AHHve}k_2CiCEugVnKlZQU*JH#Qe`FDV#c$HOmFue*8U ztM}|RZ*SWs{*r-xKj4wg+iNzhyZ`C)Yfa~t=VjSq`6j<;Xb%3sQFmE&BcXG)`po%G z8aHgMTCr?Z!^eGX{hRj6mea56$d$m7AGd}*f$rbgGABXRp(surT|=!1e;#+NX<%%8 z)E(<;`P*81@8<{N{{IBOvg2J&{nVa86~&Rd6sHcSmeg5NwcJ*BHyV2!{p9dWDJ(v9 z>J8g5$L0J=sk213L}W|EX-H&4k~AVoLt+~ery;Q|@y+iixR{Rdx?DQcqfQxHUMSP-1JXbv=}@-T(6 zJR^9%1uV`fx2~*bP2qMvJaJ@pYI@>OZ*973L2y3&z{3wbOqF-3e}HEMPdwJI+KNBB zoVJd`v(r;E`%WKB-vQvId0-I<>YK{T$2aUl0MAGnZUo;5C&%8Twx)(VuYZW~ktscP zyk%zcm+0B=+FdtL3m6fJR5dXf)BpvA@weLcufA;OM&jMiy;!LBm$UJ@M>+TXxwP}M zlM}(^&B57sEKH&EquYRUtl<7g%+ko=aR2)dofzERo0ge*z&% zL_t(IjfIm>NEC4t$G>l8ezQBfQetea8?{0R5eb5oZd-@kB39E(L?Va|C3Lc)ExLM% z5Cc2J9whM4B?^MDZXG07ijEZ?B1`vBxoncV?ac1X@AvC4nXZiPgLis=_`L6X4^m3h z@}oDkEAd-e#w(^_3yY^%9T6s@f8pk?g&&^{uN-BI;ua7-ojly%b8Xui)eNX&j06fK*uV6q8legr6j(T!&0k zi9>yj9S1wv*Iyq{u=3DUhFDV{h!hY22|!8#AqDQFFSrEp6dMW}+aL6wf4JnYuWz9D zi?6_?1E%N@l4EB68Hfl3f`qGnd$iXb;n;2VsHt)P`R?O`My|Agci-NCF&}hI2Ui3v zQGjU{P_$N1wo6b*g`Wk{x;wF^0p~U>`wvX#H%c-OZ~=##s0b5Wa!4-09SO%4;Ep?T zu9$V#I5TQr&Mtkq{`h6ue}wImt$P!YdKp45fdv46K!qMq!3+h=uRztPTF3Pwl7gwW zmRPvGEvC;EUL#+bhmgSO$PI{p6x?eHgfRMW1er0LHs*Ssa%Rk)JFqL2j^{6)W@l&L zmdoXeS6a0OUbZ??!?sW|znlwr5!8I;TJQW9ZSypA?8?gt00000NkvXXu0mjf6K)rf delta 915 zcmV;E18n?{1-l0!iBL{Q4GJ0x0000DNk~Le0000M0000M2nGNE0K~LxJCPwbe*;ZP zL_t(IjkT3cXk1kohM(`8bMMWcQu`wqjWh*~h@gVTn3*ivC=sc_`X7p2Na?04YZIX^ zqKF$2go-XqH?3lIQH>%(Ew&pKBAqHIh(VNC(}8mwWCJRpm-7b493t`#;6KfBS<05e|fHzW>yy`bM>DcHB1-?!A6f=Z8jY-&zd) zCsWPwHRsGd0<#tbK=IkZ{3=|ulv!az=dmJHU{UPmv+IO z>c4wO=bc^m2H#G9PS55+jH6OsaErP9!9VK7FdMY`_FDFpKddeGBNcDMl99@ zd@*?#BMu`5Yb=66M96P>ym1t{;b7mot2ey7qkmV+`Nb)IK6?gh0-Om*H6=|GtZ^8z z_|#xB$4MHaD6$$jKjIFye{bw~W+4Aq%jEfQn4bG-8K?{WP; zS$Tt(9UIy)h>{Td5@lZ`7K@_T5Wr(lj1|OGy=kgw35w~3e?_sB{#VV(6X*W?{m@4z z-@SCxhHkp9y@#?dlA03O3NC`M*%Gx_np!PUYxNv78&auU9;~C9e}4U%-}l$-h2dkz z4;R;m9rScQL=Xhnz~Dkd5Sc1`32JeX!B|0og>%cir6@!s0HTRE{0Fx^Rh$`5-aB%C z@AkI7&L^cX`!Q-NJh@uhW!c5T*? ze*B%>UE4P1Z`tWif6pF6Q+WN*E9G)Aj#iE?FgJe|1B4=y)EwJPuBP9gyvWGN{#8Av!##xlhOu8{-W z_eYbl%HYh8>o&{oBxWuf-PgfmU=b*(s!IKhkt#g^qHK3{6G$e_R6k`ID61~NDss8U pR75P*@7&g@Hcf4!1W0rh$lr11Sh~C<&aD6d002ovPDHLkV1m7OyDR_z diff --git a/files/opencs/resources.qrc b/files/opencs/resources.qrc index fb3c1eb3e9..2031e54cce 100644 --- a/files/opencs/resources.qrc +++ b/files/opencs/resources.qrc @@ -59,6 +59,11 @@ multitype.png go-next.png go-previous.png + edit-delete.png + edit-undo.png + edit-preview.png + edit-clone.png + add.png raster/startup/big/create-addon.png raster/startup/big/new-game.png raster/startup/big/edit-content.png From 1a1d52c51308995e505f7c39028661b74f4306b1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 20 Mar 2014 14:19:50 +0100 Subject: [PATCH 075/127] fixed a column ID problem --- apps/opencs/model/world/columnimp.hpp | 5 ++--- apps/opencs/model/world/columns.cpp | 3 ++- apps/opencs/model/world/columns.hpp | 1 + 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index def225018f..b1c61b76a5 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -37,7 +37,6 @@ namespace CSMWorld } }; - /// \note Shares ID with IdColumn. A table can not have both. template struct StringIdColumn : public Column { @@ -838,11 +837,11 @@ namespace CSMWorld } }; - /// \note Shares ID with StringIdColumn. A table can not have both. template struct IdColumn : public Column { - IdColumn() : Column (Columns::ColumnId_Id, ColumnBase::Display_String) {} + IdColumn() : Column (Columns::ColumnId_ReferenceableId, + ColumnBase::Display_Referenceable) {} virtual QVariant get (const Record& record) const { diff --git a/apps/opencs/model/world/columns.cpp b/apps/opencs/model/world/columns.cpp index 2f3911270e..7410780e08 100644 --- a/apps/opencs/model/world/columns.cpp +++ b/apps/opencs/model/world/columns.cpp @@ -172,7 +172,8 @@ namespace CSMWorld { ColumnId_Rank, "Rank" }, { ColumnId_Gender, "Gender" }, { ColumnId_PcRank, "PC Rank" }, - { ColumnId_Scope, "Scope", }, + { ColumnId_Scope, "Scope" }, + { ColumnId_ReferenceableId, "Referenceable ID" }, { ColumnId_UseValue1, "Use value 1" }, { ColumnId_UseValue2, "Use value 2" }, diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 52e022e789..855e89cade 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -166,6 +166,7 @@ namespace CSMWorld ColumnId_Gender = 153, ColumnId_PcRank = 154, ColumnId_Scope = 155, + ColumnId_ReferenceableId = 156, // Allocated to a separate value range, so we don't get a collision should we ever need // to extend the number of use values. From c9b8c69f032ea1474fdfb92a990e4347bcad344f Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 20 Mar 2014 15:14:37 +0100 Subject: [PATCH 076/127] reverted changes in the cmake --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f13ede52b..154f30161b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,8 +38,8 @@ if(EXISTS ${PROJECT_SOURCE_DIR}/.git) set(GIT_VERSION "${GIT_VERSION_MAJOR}.${GIT_VERSION_MINOR}.${GIT_VERSION_RELEASE}") -# if(NOT ${OPENMW_VERSION} STREQUAL ${GIT_VERSION}) -# message(FATAL_ERROR "Silly Zini forgot to update the version again...") + if(NOT ${OPENMW_VERSION} STREQUAL ${GIT_VERSION}) + message(FATAL_ERROR "Silly Zini forgot to update the version again...") else(NOT ${OPENMW_VERSION} STREQUAL ${GIT_VERSION}) set(OPENMW_VERSION_MAJOR ${GIT_VERSION_MAJOR}) set(OPENMW_VERSION_MINOR ${GIT_VERSION_MINOR}) From 832a10b2ac2d7997c94b8634cde596a389102f51 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 20 Mar 2014 18:25:01 +0100 Subject: [PATCH 077/127] solving problems --- CMakeLists.txt | 4 ++-- apps/opencs/model/world/columnimp.hpp | 2 +- apps/opencs/view/world/dialoguesubview.cpp | 4 ++-- apps/opencs/view/world/util.cpp | 4 +++- 4 files changed, 8 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 154f30161b..5f13ede52b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,8 +38,8 @@ if(EXISTS ${PROJECT_SOURCE_DIR}/.git) set(GIT_VERSION "${GIT_VERSION_MAJOR}.${GIT_VERSION_MINOR}.${GIT_VERSION_RELEASE}") - if(NOT ${OPENMW_VERSION} STREQUAL ${GIT_VERSION}) - message(FATAL_ERROR "Silly Zini forgot to update the version again...") +# if(NOT ${OPENMW_VERSION} STREQUAL ${GIT_VERSION}) +# message(FATAL_ERROR "Silly Zini forgot to update the version again...") else(NOT ${OPENMW_VERSION} STREQUAL ${GIT_VERSION}) set(OPENMW_VERSION_MAJOR ${GIT_VERSION_MAJOR}) set(OPENMW_VERSION_MINOR ${GIT_VERSION_MINOR}) diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 6311562a6a..4c053bfd99 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -1560,7 +1560,7 @@ namespace CSMWorld template struct ResponseColumn : public Column { - ResponseColumn() : Column (Columns::ColumnId_Response, ColumnBase::Display_String) {} + ResponseColumn() : Column (Columns::ColumnId_Response, ColumnBase::Display_LongString) {} virtual QVariant get (const Record& record) const { diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 4962acfce6..6be5da6352 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -353,7 +353,7 @@ void CSVWorld::EditWidget::remake(int row) QLabel* label = new QLabel(mTable->headerData (i, Qt::Horizontal).toString(), mMainWidget); label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); editor->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - if (! (mTable->flags (mTable->index (0, i)) & Qt::ItemIsEditable)) + if (!mTable->flags (mTable->index (0, i))) { lockedLayout->addWidget (label, locked, 0); lockedLayout->addWidget (editor, locked, 1); @@ -370,7 +370,7 @@ void CSVWorld::EditWidget::remake(int row) mWidgetMapper->setCurrentModelIndex(mTable->index(row, 0)); - this->setMinimumWidth(325); //TODO find better way to set the width + this->setMinimumWidth(325); //TODO find better way to set the width or make it customizable this->setWidget(mMainWidget); this->setWidgetResizable(true); } diff --git a/apps/opencs/view/world/util.cpp b/apps/opencs/view/world/util.cpp index a71937b085..227c5c9c5a 100644 --- a/apps/opencs/view/world/util.cpp +++ b/apps/opencs/view/world/util.cpp @@ -166,7 +166,9 @@ QWidget *CSVWorld::CommandDelegate::createEditor (QWidget *parent, const QStyleO display == CSMWorld::ColumnBase::Display_Script || display == CSMWorld::ColumnBase::Display_Race || display == CSMWorld::ColumnBase::Display_Class || - display == CSMWorld::ColumnBase::Display_Faction) + display == CSMWorld::ColumnBase::Display_Faction || + display == CSMWorld::ColumnBase::Display_Miscellaneous || + display == CSMWorld::ColumnBase::Display_Sound) { return new DropLineEdit(parent); } From ccd5e549cd9de58b61f79c7e26eb88721208d5cf Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 20 Mar 2014 19:51:11 +0100 Subject: [PATCH 078/127] moved buttons down --- CMakeLists.txt | 4 ++-- apps/opencs/view/world/dialoguesubview.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 5f13ede52b..154f30161b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,8 +38,8 @@ if(EXISTS ${PROJECT_SOURCE_DIR}/.git) set(GIT_VERSION "${GIT_VERSION_MAJOR}.${GIT_VERSION_MINOR}.${GIT_VERSION_RELEASE}") -# if(NOT ${OPENMW_VERSION} STREQUAL ${GIT_VERSION}) -# message(FATAL_ERROR "Silly Zini forgot to update the version again...") + if(NOT ${OPENMW_VERSION} STREQUAL ${GIT_VERSION}) + message(FATAL_ERROR "Silly Zini forgot to update the version again...") else(NOT ${OPENMW_VERSION} STREQUAL ${GIT_VERSION}) set(OPENMW_VERSION_MAJOR ${GIT_VERSION_MAJOR}) set(OPENMW_VERSION_MINOR ${GIT_VERSION_MINOR}) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 6be5da6352..492fa920fe 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -447,7 +447,6 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM connect(mEditWidget, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SLOT(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); - mMainLayout->addLayout(buttonsLayout); mMainLayout->addWidget(mEditWidget); mEditWidget->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); @@ -466,6 +465,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM } dataChanged(mTable->index(mRow, 0)); + mMainLayout->addLayout(buttonsLayout); setWidget(mainWidget); } From a692ce99fa82f313a803cae30bbff13204225d99 Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 20 Mar 2014 20:26:53 +0100 Subject: [PATCH 079/127] =?UTF-8?q?where=20was=20my=20mind=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/opencs/model/world/columnimp.hpp | 4 ++-- apps/opencs/view/world/dialoguesubview.cpp | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/columnimp.hpp b/apps/opencs/model/world/columnimp.hpp index 4c053bfd99..ccbeaf6948 100644 --- a/apps/opencs/model/world/columnimp.hpp +++ b/apps/opencs/model/world/columnimp.hpp @@ -834,7 +834,7 @@ namespace CSMWorld virtual bool isUserEditable() const { - return false; + return true; } }; @@ -1114,7 +1114,7 @@ namespace CSMWorld virtual bool isUserEditable() const { - return false; + return true; } }; diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 492fa920fe..b29d6695b7 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -353,7 +353,7 @@ void CSVWorld::EditWidget::remake(int row) QLabel* label = new QLabel(mTable->headerData (i, Qt::Horizontal).toString(), mMainWidget); label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); editor->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - if (!mTable->flags (mTable->index (0, i))) + if (! (mTable->flags (index) & Qt::ItemIsEditable)) { lockedLayout->addWidget (label, locked, 0); lockedLayout->addWidget (editor, locked, 1); From fbb619db73a145f02c23fb3c8ef5938ede48709f Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Thu, 20 Mar 2014 21:41:11 +0100 Subject: [PATCH 080/127] =?UTF-8?q?=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- apps/opencs/view/world/dialoguesubview.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index b29d6695b7..ae7c5923b1 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -353,7 +353,7 @@ void CSVWorld::EditWidget::remake(int row) QLabel* label = new QLabel(mTable->headerData (i, Qt::Horizontal).toString(), mMainWidget); label->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); editor->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Fixed); - if (! (mTable->flags (index) & Qt::ItemIsEditable)) + if (! (mTable->flags (mTable->index (row, i)) & Qt::ItemIsEditable)) { lockedLayout->addWidget (label, locked, 0); lockedLayout->addWidget (editor, locked, 1); From e3a9daf921f30c5a8c7540b216e0760070e6bef6 Mon Sep 17 00:00:00 2001 From: Rohit Nirmal Date: Thu, 20 Mar 2014 22:22:31 -0500 Subject: [PATCH 081/127] Play item sound when trying to sell a bound item, too. --- apps/openmw/mwgui/inventorywindow.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 16ddab584a..e9efe75e7f 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -171,6 +171,7 @@ namespace MWGui if (item.mBase.getCellRef().mRefID.size() > 6 && item.mBase.getCellRef().mRefID.substr(0,6) == "bound_") { + MWBase::Environment::get().getSoundManager()->playSound (sound, 1.0, 1.0); MWBase::Environment::get().getWindowManager()->messageBox("#{sBarterDialog12}"); return; } From 6eab9c5179725ae234a504ba10c67ab35de9ed48 Mon Sep 17 00:00:00 2001 From: slothlife Date: Fri, 21 Mar 2014 01:19:40 -0500 Subject: [PATCH 082/127] Move weather state save/load to a new class --- apps/openmw/mwworld/weather.cpp | 73 +++++++++++++-------------------- components/CMakeLists.txt | 2 +- components/esm/weatherstate.cpp | 59 ++++++++++++++++++++++++++ components/esm/weatherstate.hpp | 27 ++++++++++++ 4 files changed, 116 insertions(+), 45 deletions(-) create mode 100644 components/esm/weatherstate.cpp create mode 100644 components/esm/weatherstate.hpp diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index b74ca63935..335702c665 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -1,7 +1,6 @@ #include "weather.hpp" -#include -#include +#include #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" @@ -18,15 +17,6 @@ using namespace Ogre; using namespace MWWorld; using namespace MWSound; -#define HOUR "HOUR" -#define WINDSPEED "WNSP" -#define CURRENTWEATHER "CWTH" -#define NEXTWEATHER "NWTH" -#define CURRENTREGION "CREG" -#define FIRSTUPDATE "FUPD" -#define REMAININGTRANSITIONTIME "RTTM" -#define TIMEPASSED "TMPS" - namespace { float lerp (float x, float y, float factor) @@ -698,15 +688,18 @@ bool WeatherManager::isDark() const void WeatherManager::write(ESM::ESMWriter& writer) { + ESM::WeatherState state; + state.mHour = mHour; + state.mWindSpeed = mWindSpeed; + state.mCurrentWeather = mCurrentWeather; + state.mNextWeather = mNextWeather; + state.mCurrentRegion = mCurrentRegion; + state.mFirstUpdate = mFirstUpdate; + state.mRemainingTransitionTime = mRemainingTransitionTime; + state.mTimePassed = mTimePassed; + writer.startRecord(ESM::REC_WTHR); - writer.writeHNT(HOUR, mHour); - writer.writeHNT(WINDSPEED, mWindSpeed); - writer.writeHNCString(CURRENTWEATHER, mCurrentWeather.c_str()); - writer.writeHNCString(NEXTWEATHER, mNextWeather.c_str()); - writer.writeHNCString(CURRENTREGION, mCurrentRegion.c_str()); - writer.writeHNT(FIRSTUPDATE, mFirstUpdate); - writer.writeHNT(REMAININGTRANSITIONTIME, mRemainingTransitionTime); - writer.writeHNT(TIMEPASSED, mTimePassed); + state.save(writer); writer.endRecord(ESM::REC_WTHR); } @@ -714,35 +707,27 @@ bool WeatherManager::readRecord(ESM::ESMReader& reader, int32_t type) { if(ESM::REC_WTHR == type) { - // store state in locals so that if we fail to load, we don't leave the manager in a half-way state - float newHour = 0.0; - reader.getHNT(newHour, HOUR); - float newWindSpeed = 0.0; - reader.getHNT(newWindSpeed, WINDSPEED); - std::string newCurrentWeather = reader.getHNString(CURRENTWEATHER); - std::string newNextWeather = reader.getHNString(NEXTWEATHER); - std::string newCurrentRegion = reader.getHNString(CURRENTREGION); - bool newFirstUpdate = false; - reader.getHNT(newFirstUpdate, FIRSTUPDATE); - float newRemainingTransitionTime = 0.0; - reader.getHNT(newRemainingTransitionTime, REMAININGTRANSITIONTIME); - double newTimePassed = 0.0; - reader.getHNT(newTimePassed, TIMEPASSED); + // load first so that if it fails, we haven't accidentally reset the state below + ESM::WeatherState state; + state.load(reader); - // reset other temporary state + // reset other temporary state, now that we loaded successfully + stopSounds(true); // let's hope this never throws mRegionOverrides.clear(); - stopSounds(true); // TODO: inconsistent state if this throws... mRegionMods.clear(); + mThunderFlash = 0.0; + mThunderChance = 0.0; + mThunderChanceNeeded = 50.0; - // swap in new values, now that we can't fail - mHour = newHour; - mWindSpeed = newWindSpeed; - mCurrentWeather.swap(newCurrentWeather); - mNextWeather.swap(newNextWeather); - mCurrentRegion.swap(newCurrentRegion); - mFirstUpdate = newFirstUpdate; - mRemainingTransitionTime = newRemainingTransitionTime; - mTimePassed = newTimePassed; + // swap in the loaded values now that we can't fail + mHour = state.mHour; + mWindSpeed = state.mWindSpeed; + mCurrentWeather.swap(state.mCurrentWeather); + mNextWeather.swap(state.mNextWeather); + mCurrentRegion.swap(state.mCurrentRegion); + mFirstUpdate = state.mFirstUpdate; + mRemainingTransitionTime = state.mRemainingTransitionTime; + mTimePassed = state.mTimePassed; return true; } diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index db4ecad0b1..c4d13170d0 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -45,7 +45,7 @@ add_component_dir (esm loadnpc loadpgrd loadrace loadregn loadscpt loadskil loadsndg loadsoun loadspel loadsscr loadstat loadweap records aipackage effectlist spelllist variant variantimp loadtes3 cellref filter savedgame journalentry queststate locals globalscript player objectstate cellid cellstate globalmap lightstate inventorystate containerstate npcstate creaturestate dialoguestate statstate - npcstats creaturestats + npcstats creaturestats weatherstate ) add_component_dir (misc diff --git a/components/esm/weatherstate.cpp b/components/esm/weatherstate.cpp new file mode 100644 index 0000000000..48cf55a600 --- /dev/null +++ b/components/esm/weatherstate.cpp @@ -0,0 +1,59 @@ +#include "weatherstate.hpp" + +#include "esmreader.hpp" +#include "esmwriter.hpp" + +namespace +{ + const char* hourRecord = "HOUR"; + const char* windSpeedRecord = "WNSP"; + const char* currentWeatherRecord = "CWTH"; + const char* nextWeatherRecord = "NWTH"; + const char* currentRegionRecord = "CREG"; + const char* firstUpdateRecord = "FUPD"; + const char* remainingTransitionTimeRecord = "RTTM"; + const char* timePassedRecord = "TMPS"; +} + +namespace ESM +{ + void WeatherState::load(ESMReader& esm) + { + // store values locally so that a failed load can't leave the state half set + float newHour = 0.0; + esm.getHNT(newHour, hourRecord); + float newWindSpeed = 0.0; + esm.getHNT(newWindSpeed, windSpeedRecord); + std::string newCurrentWeather = esm.getHNString(currentWeatherRecord); + std::string newNextWeather = esm.getHNString(nextWeatherRecord); + std::string newCurrentRegion = esm.getHNString(currentRegionRecord); + bool newFirstUpdate = false; + esm.getHNT(newFirstUpdate, firstUpdateRecord); + float newRemainingTransitionTime = 0.0; + esm.getHNT(newRemainingTransitionTime, remainingTransitionTimeRecord); + double newTimePassed = 0.0; + esm.getHNT(newTimePassed, timePassedRecord); + + // swap values now that it is safe to do so + mHour = newHour; + mWindSpeed = newWindSpeed; + mCurrentWeather.swap(newCurrentWeather); + mNextWeather.swap(newNextWeather); + mCurrentRegion.swap(newCurrentRegion); + mFirstUpdate = newFirstUpdate; + mRemainingTransitionTime = newRemainingTransitionTime; + mTimePassed = newTimePassed; + } + + void WeatherState::save(ESMWriter& esm) const + { + esm.writeHNT(hourRecord, mHour); + esm.writeHNT(windSpeedRecord, mWindSpeed); + esm.writeHNCString(currentWeatherRecord, mCurrentWeather.c_str()); + esm.writeHNCString(nextWeatherRecord, mNextWeather.c_str()); + esm.writeHNCString(currentRegionRecord, mCurrentRegion.c_str()); + esm.writeHNT(firstUpdateRecord, mFirstUpdate); + esm.writeHNT(remainingTransitionTimeRecord, mRemainingTransitionTime); + esm.writeHNT(timePassedRecord, mTimePassed); + } +} diff --git a/components/esm/weatherstate.hpp b/components/esm/weatherstate.hpp new file mode 100644 index 0000000000..5457512252 --- /dev/null +++ b/components/esm/weatherstate.hpp @@ -0,0 +1,27 @@ +#ifndef OPENMW_ESM_WEATHER_H +#define OPENMW_ESM_WEATHER_H + +#include + +namespace ESM +{ + class ESMReader; + class ESMWriter; + + struct WeatherState + { + float mHour; + float mWindSpeed; + std::string mCurrentWeather; + std::string mNextWeather; + std::string mCurrentRegion; + bool mFirstUpdate; + float mRemainingTransitionTime; + double mTimePassed; + + void load(ESMReader& esm); + void save(ESMWriter& esm) const; + }; +} + +#endif From 00eac7d53adc272424fa029a4eaaed262396750e Mon Sep 17 00:00:00 2001 From: slothlife Date: Fri, 21 Mar 2014 01:22:54 -0500 Subject: [PATCH 083/127] Fixed header include guard to match filename --- components/esm/weatherstate.hpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/components/esm/weatherstate.hpp b/components/esm/weatherstate.hpp index 5457512252..d0cd59c160 100644 --- a/components/esm/weatherstate.hpp +++ b/components/esm/weatherstate.hpp @@ -1,5 +1,5 @@ -#ifndef OPENMW_ESM_WEATHER_H -#define OPENMW_ESM_WEATHER_H +#ifndef OPENMW_ESM_WEATHERSTATE_H +#define OPENMW_ESM_WEATHERSTATE_H #include From 6dce3e51864e9fc8799690c132b5e7d4e868ddf2 Mon Sep 17 00:00:00 2001 From: slothlife Date: Fri, 21 Mar 2014 01:33:11 -0500 Subject: [PATCH 084/127] Fixed include to use C99 header, not C++11 header --- apps/openmw/mwworld/weather.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/openmw/mwworld/weather.hpp b/apps/openmw/mwworld/weather.hpp index 3167a64c2a..cad3a4492e 100644 --- a/apps/openmw/mwworld/weather.hpp +++ b/apps/openmw/mwworld/weather.hpp @@ -1,7 +1,7 @@ #ifndef GAME_MWWORLD_WEATHER_H #define GAME_MWWORLD_WEATHER_H -#include +#include #include #include From 10ce47938b3de5f6a556b72acfbf4aef41c6a491 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 21 Mar 2014 11:22:43 +0100 Subject: [PATCH 085/127] update preview on reference/referenceable changes --- apps/opencs/view/render/previewwidget.cpp | 134 ++++++++++++++++++---- apps/opencs/view/render/previewwidget.hpp | 30 +++-- apps/opencs/view/render/scenewidget.cpp | 5 + apps/opencs/view/render/scenewidget.hpp | 2 + 4 files changed, 139 insertions(+), 32 deletions(-) diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp index 43d45f4cb9..9b64cf6f4e 100644 --- a/apps/opencs/view/render/previewwidget.cpp +++ b/apps/opencs/view/render/previewwidget.cpp @@ -4,36 +4,55 @@ #include #include "../../model/world/data.hpp" +#include "../../model/world/idtable.hpp" -void CSVRender::PreviewWidget::setup (const std::string& id) +void CSVRender::PreviewWidget::setup() { setNavigation (&mOrbit); - int column = mData.getReferenceables().findColumnIndex (CSMWorld::Columns::ColumnId_Model); - - int row = mData.getReferenceables().getIndex (id); - - QVariant value = mData.getReferenceables().getData (row, column); - - if (!value.isValid()) - return; - - std::string model = value.toString().toUtf8().constData(); - - if (model.empty()) - return; - mNode = getSceneManager()->getRootSceneNode()->createChildSceneNode(); mNode->setPosition (Ogre::Vector3 (0, 0, 0)); - mObject = NifOgre::Loader::createObjects (mNode, "Meshes\\" + model); + setModel(); + + QAbstractItemModel *referenceables = + mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables); + + connect (referenceables, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), + this, SLOT (ReferenceableDataChanged (const QModelIndex&, const QModelIndex&))); + connect (referenceables, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), + this, SLOT (ReferenceableAboutToBeRemoved (const QModelIndex&, int, int))); } -void CSVRender::PreviewWidget::adjust (const std::string& id) +void CSVRender::PreviewWidget::setModel() { if (mNode) { - int row = mData.getReferences().getIndex (id); + mObject.setNull(); + + int column = mData.getReferenceables().findColumnIndex (CSMWorld::Columns::ColumnId_Model); + + int row = mData.getReferenceables().getIndex (mReferenceableId); + + QVariant value = mData.getReferenceables().getData (row, column); + + if (!value.isValid()) + return; + + std::string model = value.toString().toUtf8().constData(); + + if (model.empty()) + return; + + mObject = NifOgre::Loader::createObjects (mNode, "Meshes\\" + model); + } +} + +void CSVRender::PreviewWidget::adjust() +{ + if (mNode) + { + int row = mData.getReferences().getIndex (mReferenceId); float scale = mData.getReferences().getData (row, mData.getReferences(). findColumnIndex (CSMWorld::Columns::ColumnId_Scale)).toFloat(); @@ -56,17 +75,82 @@ void CSVRender::PreviewWidget::adjust (const std::string& id) } } -CSVRender::PreviewWidget::PreviewWidget (const CSMWorld::Data& data, +CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId, QWidget *parent) -: SceneWidget (parent), mData (data), mNode (0) +: SceneWidget (parent), mData (data), mNode (0), mReferenceableId (referenceableId) { - setup (referenceableId); + setup(); } -CSVRender::PreviewWidget::PreviewWidget (const CSMWorld::Data& data, +CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId, const std::string& referenceId, QWidget *parent) -: SceneWidget (parent), mData (data) +: SceneWidget (parent), mData (data), mReferenceableId (referenceableId), + mReferenceId (referenceId) { - setup (referenceableId); - adjust (referenceId); + setup(); + + adjust(); + + QAbstractItemModel *references = + mData.getTableModel (CSMWorld::UniversalId::Type_References); + + connect (references, SIGNAL (dataChanged (const QModelIndex&, const QModelIndex&)), + this, SLOT (ReferenceDataChanged (const QModelIndex&, const QModelIndex&))); + connect (references, SIGNAL (rowsAboutToBeRemoved (const QModelIndex&, int, int)), + this, SLOT (ReferenceAboutToBeRemoved (const QModelIndex&, int, int))); +} + +void CSVRender::PreviewWidget::ReferenceableDataChanged (const QModelIndex& topLeft, + const QModelIndex& bottomRight) +{ + CSMWorld::IdTable& referenceables = dynamic_cast ( + *mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables)); + + QModelIndex index = referenceables.getModelIndex (mReferenceableId, 0); + + if (index.row()>=topLeft.row() && index.row()<=bottomRight.row()) + { + /// \todo possible optimisation; check columns and only update if relevant columns have + /// changed + setModel(); + flagAsModified(); + } +} + +void CSVRender::PreviewWidget::ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start, + int end) +{ + +} + +void CSVRender::PreviewWidget::ReferenceDataChanged (const QModelIndex& topLeft, + const QModelIndex& bottomRight) +{ + CSMWorld::IdTable& references = dynamic_cast ( + *mData.getTableModel (CSMWorld::UniversalId::Type_References)); + + int columnIndex = references.findColumnIndex (CSMWorld::Columns::ColumnId_ReferenceableId); + + QModelIndex index = references.getModelIndex (mReferenceId, columnIndex); + + if (index.row()>=topLeft.row() && index.row()<=bottomRight.row()) + { + /// \todo possible optimisation; check columns and only update if relevant columns have + /// changed + adjust(); + + if (index.column()>=topLeft.column() && index.column()<=bottomRight.row()) + { + mReferenceableId = references.data (index).toString().toUtf8().constData(); + setModel(); + } + + flagAsModified(); + } +} + +void CSVRender::PreviewWidget::ReferenceAboutToBeRemoved (const QModelIndex& parent, int start, + int end) +{ + } diff --git a/apps/opencs/view/render/previewwidget.hpp b/apps/opencs/view/render/previewwidget.hpp index b3abd55879..2b6517e715 100644 --- a/apps/opencs/view/render/previewwidget.hpp +++ b/apps/opencs/view/render/previewwidget.hpp @@ -7,6 +7,8 @@ #include "navigationorbit.hpp" +class QModelIndex; + namespace CSMWorld { class Data; @@ -18,28 +20,42 @@ namespace CSVRender { Q_OBJECT - const CSMWorld::Data& mData; + CSMWorld::Data& mData; CSVRender::NavigationOrbit mOrbit; NifOgre::ObjectScenePtr mObject; Ogre::SceneNode *mNode; + std::string mReferenceId; + std::string mReferenceableId; - void setup (const std::string& id); - ///< \param id ID of the referenceable to be viewed + void setup(); - void adjust (const std::string& id); - ///< \param id ID of the reference to be viewed + void setModel(); + + void adjust(); + ///< Adjust referenceable preview according to the reference public: - PreviewWidget (const CSMWorld::Data& data, const std::string& referenceableId, + PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId, QWidget *parent = 0); - PreviewWidget (const CSMWorld::Data& data, const std::string& referenceableId, + PreviewWidget (CSMWorld::Data& data, const std::string& referenceableId, const std::string& referenceId, QWidget *parent = 0); signals: void closeRequest(); + + private slots: + + void ReferenceableDataChanged (const QModelIndex& topLeft, + const QModelIndex& bottomRight); + + void ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end); + + void ReferenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight); + + void ReferenceAboutToBeRemoved (const QModelIndex& parent, int start, int end); }; } diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 5eec702d3d..6b2ca85b5e 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -118,6 +118,11 @@ namespace CSVRender return mSceneMgr; } + void SceneWidget::flagAsModified() + { + mUpdate = true; + } + void SceneWidget::paintEvent(QPaintEvent* e) { if (!mWindow) diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 05b06b2873..375c877d22 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -36,6 +36,8 @@ namespace CSVRender Ogre::SceneManager *getSceneManager(); + void flagAsModified(); + private: void paintEvent(QPaintEvent* e); void resizeEvent(QResizeEvent* e); From fc8ae2b9b563d7713b909333ad2c228764b0e53b Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 21 Mar 2014 11:56:48 +0100 Subject: [PATCH 086/127] fixed encoding problems --- apps/opencs/editor.cpp | 8 ++++---- apps/opencs/model/tools/tools.cpp | 2 +- apps/opencs/model/world/tablemimedata.cpp | 4 ++-- apps/opencs/view/doc/opendialog.cpp | 2 +- apps/opencs/view/doc/subview.cpp | 2 +- apps/opencs/view/filter/editwidget.cpp | 4 ++-- apps/opencs/view/world/dialoguesubview.cpp | 14 +++++++------- apps/opencs/view/world/scriptedit.cpp | 6 +++--- apps/opencs/view/world/table.cpp | 6 +++--- 9 files changed, 24 insertions(+), 24 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 942780c32b..87660a60bc 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -61,7 +61,7 @@ void CS::Editor::setupDataFiles (const Files::PathContainer& dataDirs) { for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter) { - QString path = QString::fromStdString(iter->string()); + QString path = QString::fromUtf8 (iter->string().c_str()); mFileDialog.addFiles(path); } } @@ -148,7 +148,7 @@ void CS::Editor::openFiles (const boost::filesystem::path &savePath) std::vector files; foreach (const QString &path, mFileDialog.selectedFilePaths()) - files.push_back(path.toStdString()); + files.push_back(path.toUtf8().constData()); CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, false); @@ -161,10 +161,10 @@ void CS::Editor::createNewFile (const boost::filesystem::path &savePath) std::vector files; foreach (const QString &path, mFileDialog.selectedFilePaths()) { - files.push_back(path.toStdString()); + files.push_back(path.toUtf8().constData()); } - files.push_back(mFileDialog.filename().toStdString()); + files.push_back(mFileDialog.filename().toUtf8().constData()); CSMDoc::Document *document = mDocumentManager.addDocument (files, savePath, true); diff --git a/apps/opencs/model/tools/tools.cpp b/apps/opencs/model/tools/tools.cpp index 79a09dcb48..d3d8f5fadd 100644 --- a/apps/opencs/model/tools/tools.cpp +++ b/apps/opencs/model/tools/tools.cpp @@ -143,6 +143,6 @@ void CSMTools::Tools::verifierMessage (const QString& message, int type) std::map::iterator iter = mActiveReports.find (type); if (iter!=mActiveReports.end()) - mReports[iter->second]->add (message.toStdString()); + mReports[iter->second]->add (message.toUtf8().constData()); } diff --git a/apps/opencs/model/world/tablemimedata.cpp b/apps/opencs/model/world/tablemimedata.cpp index 9dcecf3bc1..ccd6fb4964 100644 --- a/apps/opencs/model/world/tablemimedata.cpp +++ b/apps/opencs/model/world/tablemimedata.cpp @@ -8,7 +8,7 @@ CSMWorld::TableMimeData::TableMimeData (UniversalId id, const CSMDoc::Document& mDocument(document) { mUniversalId.push_back (id); - mObjectsFormats << QString::fromStdString ("tabledata/" + id.getTypeName()); + mObjectsFormats << QString::fromUtf8 (("tabledata/" + id.getTypeName()).c_str()); } CSMWorld::TableMimeData::TableMimeData (std::vector< CSMWorld::UniversalId >& id, const CSMDoc::Document& document) : @@ -16,7 +16,7 @@ CSMWorld::TableMimeData::TableMimeData (std::vector< CSMWorld::UniversalId >& id { for (std::vector::iterator it (mUniversalId.begin()); it != mUniversalId.end(); ++it) { - mObjectsFormats << QString::fromStdString ("tabledata/" + it->getTypeName()); + mObjectsFormats << QString::fromUtf8 (("tabledata/" + it->getTypeName()).c_str()); } } diff --git a/apps/opencs/view/doc/opendialog.cpp b/apps/opencs/view/doc/opendialog.cpp index 7b62aafa31..d107b198c6 100644 --- a/apps/opencs/view/doc/opendialog.cpp +++ b/apps/opencs/view/doc/opendialog.cpp @@ -40,7 +40,7 @@ OpenDialog::OpenDialog(QWidget * parent) : QDialog(parent) mCfgMgr.processPaths(mDataLocal); // Set the charset for reading the esm/esp files - QString encoding = QString::fromStdString(variables["encoding"].as()); + QString encoding = QString::fromUtf8 (variables["encoding"].as().c_str()); Files::PathContainer dataDirs; dataDirs.insert(dataDirs.end(), mDataDirs.begin(), mDataDirs.end()); diff --git a/apps/opencs/view/doc/subview.cpp b/apps/opencs/view/doc/subview.cpp index dcd85945fc..7fd0057173 100644 --- a/apps/opencs/view/doc/subview.cpp +++ b/apps/opencs/view/doc/subview.cpp @@ -4,7 +4,7 @@ CSVDoc::SubView::SubView (const CSMWorld::UniversalId& id) : mUniversalId (id) { /// \todo add a button to the title bar that clones this sub view - setWindowTitle (mUniversalId.toString().c_str()); + setWindowTitle (QString::fromUtf8 (mUniversalId.toString().c_str())); } CSMWorld::UniversalId CSVDoc::SubView::getUniversalId() const diff --git a/apps/opencs/view/filter/editwidget.cpp b/apps/opencs/view/filter/editwidget.cpp index cc1578bdd9..b163297f9a 100644 --- a/apps/opencs/view/filter/editwidget.cpp +++ b/apps/opencs/view/filter/editwidget.cpp @@ -120,7 +120,7 @@ void CSVFilter::EditWidget::createFilterRequest (std::vector< std::pair< std::st { ss<<"!or("; } else { - ss << orAnd << oldContent.toStdString() << ','; + ss << orAnd << oldContent.toUtf8().constData() << ','; } for (unsigned i = 0; i < count; ++i) @@ -137,7 +137,7 @@ void CSVFilter::EditWidget::createFilterRequest (std::vector< std::pair< std::st } else { if (!replaceMode) { - ss << orAnd << oldContent.toStdString() <<','; + ss << orAnd << oldContent.toUtf8().constData() <<','; } else { ss<<'!'; } diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index ae7c5923b1..1627bc5f4f 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -444,7 +444,7 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM mMainLayout = new QVBoxLayout(mainWidget); mEditWidget = new EditWidget(mainWidget, mRow, mTable, mUndoStack, false); - connect(mEditWidget, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), + connect(mEditWidget, SIGNAL(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*)), this, SLOT(tableMimeDataDropped(QWidget*, const QModelIndex&, const CSMWorld::UniversalId&, const CSMDoc::Document*))); mMainLayout->addWidget(mEditWidget); @@ -490,7 +490,7 @@ void CSVWorld::DialogueSubView::prevId() { mEditWidget->remake(newRow); setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), - mTable->data (mTable->index (newRow, 0)).toString().toStdString())); + mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); mRow = newRow; mEditWidget->setDisabled(mLocked); return; @@ -522,7 +522,7 @@ void CSVWorld::DialogueSubView::nextId() { mEditWidget->remake(newRow); setUniversalId(CSMWorld::UniversalId (static_cast (mTable->data (mTable->index (newRow, 2)).toInt()), - mTable->data (mTable->index (newRow, 0)).toString().toStdString())); + mTable->data (mTable->index (newRow, 0)).toString().toUtf8().constData())); mRow = newRow; mEditWidget->setDisabled(mLocked); return; @@ -580,7 +580,7 @@ void CSVWorld::DialogueSubView::revertRecord() if (state!=CSMWorld::RecordBase::State_BaseOnly) { - mUndoStack.push(new CSMWorld::RevertCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toStdString())); + mUndoStack.push(new CSMWorld::RevertCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData())); } if (rows != mTable->rowCount()) { @@ -613,7 +613,7 @@ void CSVWorld::DialogueSubView::deleteRecord() mRow < rows && mBottom->canCreateAndDelete()) { - mUndoStack.push(new CSMWorld::DeleteCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toStdString())); + mUndoStack.push(new CSMWorld::DeleteCommand(*mTable, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData())); if (rows != mTable->rowCount()) { if (mTable->rowCount() == 0) @@ -639,7 +639,7 @@ void CSVWorld::DialogueSubView::requestFocus (const std::string& id) void CSVWorld::DialogueSubView::cloneRequest () { - mBottom->cloneRequest(mTable->data(mTable->index (mRow, 0)).toString().toStdString(), + mBottom->cloneRequest(mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData(), static_cast(mTable->data(mTable->index(mRow, 2)).toInt())); } @@ -647,7 +647,7 @@ void CSVWorld::DialogueSubView::showPreview () { if (mTable->hasPreview() && mRow < mTable->rowCount()) { - emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, mTable->data(mTable->index (mRow, 0)).toString().toStdString()), ""); + emit focusId(CSMWorld::UniversalId(CSMWorld::UniversalId::Type_Preview, mTable->data(mTable->index (mRow, 0)).toString().toUtf8().constData()), ""); } } diff --git a/apps/opencs/view/world/scriptedit.cpp b/apps/opencs/view/world/scriptedit.cpp index fccac75b41..b1528d5254 100644 --- a/apps/opencs/view/world/scriptedit.cpp +++ b/apps/opencs/view/world/scriptedit.cpp @@ -71,9 +71,9 @@ void CSVWorld::ScriptEdit::dropEvent (QDropEvent* event) { if (stringNeedsQuote(it->getId())) { - insertPlainText(QString::fromStdString ('"' + it->getId() + '"')); + insertPlainText(QString::fromUtf8 (('"' + it->getId() + '"').c_str())); } else { - insertPlainText(QString::fromStdString (it->getId())); + insertPlainText(QString::fromUtf8 (it->getId().c_str())); } } } @@ -82,7 +82,7 @@ void CSVWorld::ScriptEdit::dropEvent (QDropEvent* event) bool CSVWorld::ScriptEdit::stringNeedsQuote (const std::string& id) const { - const QString string(QString::fromStdString(id)); // is only for c++11, so let's use qregexp for now. + const QString string(QString::fromUtf8(id.c_str())); // is only for c++11, so let's use qregexp for now. //I'm not quite sure when do we need to put quotes. To be safe we will use quotes for anything other than… return !(string.contains(mWhiteListQoutes)); } diff --git a/apps/opencs/view/world/table.cpp b/apps/opencs/view/world/table.cpp index cd9138c357..a2927c2f09 100644 --- a/apps/opencs/view/world/table.cpp +++ b/apps/opencs/view/world/table.cpp @@ -289,7 +289,7 @@ CSMWorld::UniversalId CSVWorld::Table::getUniversalId (int row) const { return CSMWorld::UniversalId ( static_cast (mProxyModel->data (mProxyModel->index (row, 2)).toInt()), - mProxyModel->data (mProxyModel->index (row, 0)).toString().toStdString()); + mProxyModel->data (mProxyModel->index (row, 0)).toString().toUtf8().constData()); } void CSVWorld::Table::revertRecord() @@ -533,7 +533,7 @@ void CSVWorld::Table::mouseMoveEvent (QMouseEvent* event) } drag->setMimeData (mime); - drag->setPixmap (QString::fromStdString (mime->getIcon())); + drag->setPixmap (QString::fromUtf8 (mime->getIcon().c_str())); drag->exec(Qt::CopyAction); } @@ -588,7 +588,7 @@ std::vector CSVWorld::Table::getColumnsWithDisplay(CSMWorld::Column if (display == columndisplay) { - titles.push_back(mModel->headerData (i, Qt::Horizontal).toString().toStdString()); + titles.push_back(mModel->headerData (i, Qt::Horizontal).toString().toUtf8().constData()); } } return titles; From 2a26ff2299923f9c0baab0e316408e9adc4ce0ec Mon Sep 17 00:00:00 2001 From: Marek Kochanowicz Date: Fri, 21 Mar 2014 12:13:54 +0100 Subject: [PATCH 087/127] better fix --- apps/opencs/model/world/tablemimedata.cpp | 99 ++++++++++++++++++++-- apps/opencs/model/world/tablemimedata.hpp | 8 +- apps/opencs/view/world/dialoguesubview.cpp | 43 ++++++++-- 3 files changed, 131 insertions(+), 19 deletions(-) diff --git a/apps/opencs/model/world/tablemimedata.cpp b/apps/opencs/model/world/tablemimedata.cpp index 9dcecf3bc1..f6256c2634 100644 --- a/apps/opencs/model/world/tablemimedata.cpp +++ b/apps/opencs/model/world/tablemimedata.cpp @@ -64,14 +64,69 @@ std::vector< CSMWorld::UniversalId > CSMWorld::TableMimeData::getData() const return mUniversalId; } +bool CSMWorld::TableMimeData::isReferencable(CSMWorld::ColumnBase::Display type) const +{ +return ( type == CSMWorld::ColumnBase::Display_Activator + || type == CSMWorld::ColumnBase::Display_Potion + || type == CSMWorld::ColumnBase::Display_Apparatus + || type == CSMWorld::ColumnBase::Display_Armor + || type == CSMWorld::ColumnBase::Display_Book + || type == CSMWorld::ColumnBase::Display_Clothing + || type == CSMWorld::ColumnBase::Display_Container + || type == CSMWorld::ColumnBase::Display_Creature + || type == CSMWorld::ColumnBase::Display_Door + || type == CSMWorld::ColumnBase::Display_Ingredient + || type == CSMWorld::ColumnBase::Display_CreatureLevelledList + || type == CSMWorld::ColumnBase::Display_ItemLevelledList + || type == CSMWorld::ColumnBase::Display_Light + || type == CSMWorld::ColumnBase::Display_Lockpick + || type == CSMWorld::ColumnBase::Display_Miscellaneous + || type == CSMWorld::ColumnBase::Display_Npc + || type == CSMWorld::ColumnBase::Display_Probe + || type == CSMWorld::ColumnBase::Display_Repair + || type == CSMWorld::ColumnBase::Display_Static + || type == CSMWorld::ColumnBase::Display_Weapon); +} +bool CSMWorld::TableMimeData::isReferencable(CSMWorld::UniversalId::Type type) const +{ + return ( type == CSMWorld::UniversalId::Type_Activator + || type == CSMWorld::UniversalId::Type_Potion + || type == CSMWorld::UniversalId::Type_Apparatus + || type == CSMWorld::UniversalId::Type_Armor + || type == CSMWorld::UniversalId::Type_Book + || type == CSMWorld::UniversalId::Type_Clothing + || type == CSMWorld::UniversalId::Type_Container + || type == CSMWorld::UniversalId::Type_Creature + || type == CSMWorld::UniversalId::Type_Door + || type == CSMWorld::UniversalId::Type_Ingredient + || type == CSMWorld::UniversalId::Type_CreatureLevelledList + || type == CSMWorld::UniversalId::Type_ItemLevelledList + || type == CSMWorld::UniversalId::Type_Light + || type == CSMWorld::UniversalId::Type_Lockpick + || type == CSMWorld::UniversalId::Type_Miscellaneous + || type == CSMWorld::UniversalId::Type_Npc + || type == CSMWorld::UniversalId::Type_Probe + || type == CSMWorld::UniversalId::Type_Repair + || type == CSMWorld::UniversalId::Type_Static + || type == CSMWorld::UniversalId::Type_Weapon); +} bool CSMWorld::TableMimeData::holdsType (CSMWorld::UniversalId::Type type) const { + bool referencable = (type == CSMWorld::UniversalId::Type_Referenceable); for (std::vector::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it) { - if (it->getType() == type) + if (referencable) { - return true; + if (isReferencable(it->getType())) + { + return true; + } + } else { + if (it->getType() == type) + { + return true; + } } } @@ -80,11 +135,20 @@ bool CSMWorld::TableMimeData::holdsType (CSMWorld::UniversalId::Type type) const bool CSMWorld::TableMimeData::holdsType (CSMWorld::ColumnBase::Display type) const { + bool referencable = (type == CSMWorld::ColumnBase::Display_Referenceable); for (std::vector::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it) { - if (it->getType() == convertEnums (type)) + if (referencable) { - return true; + if (isReferencable(it->getType())) + { + return true; + } + } else { + if (it->getType() == convertEnums (type)) + { + return true; + } } } @@ -93,11 +157,21 @@ bool CSMWorld::TableMimeData::holdsType (CSMWorld::ColumnBase::Display type) con CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::UniversalId::Type type) const { + bool referencable = (type == CSMWorld::UniversalId::Type_Referenceable); for (std::vector::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it) { - if (it->getType() == type) + if (referencable) { - return *it; + if (isReferencable(it->getType())) + { + return *it; + } + } else + { + if (it->getType() == type) + { + return *it; + } } } @@ -106,11 +180,20 @@ CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::Univers CSMWorld::UniversalId CSMWorld::TableMimeData::returnMatching (CSMWorld::ColumnBase::Display type) const { + bool referencable = (type == CSMWorld::ColumnBase::Display_Referenceable); for (std::vector::const_iterator it = mUniversalId.begin(); it != mUniversalId.end(); ++it) { - if (it->getType() == convertEnums (type)) + if (referencable) { - return *it; + if (isReferencable(it->getType())) + { + return *it; + } + } else { + if (it->getType() == convertEnums (type)) + { + return *it; + } } } diff --git a/apps/opencs/model/world/tablemimedata.hpp b/apps/opencs/model/world/tablemimedata.hpp index 44ac0f5f64..adcb147c18 100644 --- a/apps/opencs/model/world/tablemimedata.hpp +++ b/apps/opencs/model/world/tablemimedata.hpp @@ -27,6 +27,9 @@ namespace CSMWorld class TableMimeData : public QMimeData { + std::vector mUniversalId; + QStringList mObjectsFormats; + const CSMDoc::Document& mDocument; public: TableMimeData(UniversalId id, const CSMDoc::Document& document); @@ -56,9 +59,8 @@ namespace CSMWorld static CSMWorld::ColumnBase::Display convertEnums(CSMWorld::UniversalId::Type type); private: - std::vector mUniversalId; - QStringList mObjectsFormats; - const CSMDoc::Document& mDocument; + bool isReferencable(CSMWorld::UniversalId::Type type) const; + bool isReferencable(CSMWorld::ColumnBase::Display type) const; }; } diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index ae7c5923b1..cf932aba11 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -122,18 +122,45 @@ void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std:: { QLineEdit* lineEdit = qobject_cast(mEditor); { - if (!lineEdit or !mIndexWrapper.get()) - { - return; - } + if (!lineEdit or !mIndexWrapper.get()) + { + return; + } } for (unsigned i = 0; i < data.size(); ++i) { - if (mDisplay == CSMWorld::TableMimeData::convertEnums(data[i].getType())) + CSMWorld::UniversalId::Type type = data[i].getType(); + if (mDisplay == CSMWorld::ColumnBase::Display_Referenceable) { - emit tableMimeDataDropped(mEditor, mIndexWrapper->mIndex, data[i], document); - emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay); - break; + if ( type == CSMWorld::UniversalId::Type_Activator + || type == CSMWorld::UniversalId::Type_Potion + || type == CSMWorld::UniversalId::Type_Apparatus + || type == CSMWorld::UniversalId::Type_Armor + || type == CSMWorld::UniversalId::Type_Book + || type == CSMWorld::UniversalId::Type_Clothing + || type == CSMWorld::UniversalId::Type_Container + || type == CSMWorld::UniversalId::Type_Creature + || type == CSMWorld::UniversalId::Type_Door + || type == CSMWorld::UniversalId::Type_Ingredient + || type == CSMWorld::UniversalId::Type_CreatureLevelledList + || type == CSMWorld::UniversalId::Type_ItemLevelledList + || type == CSMWorld::UniversalId::Type_Light + || type == CSMWorld::UniversalId::Type_Lockpick + || type == CSMWorld::UniversalId::Type_Miscellaneous + || type == CSMWorld::UniversalId::Type_Npc + || type == CSMWorld::UniversalId::Type_Probe + || type == CSMWorld::UniversalId::Type_Repair + || type == CSMWorld::UniversalId::Type_Static + || type == CSMWorld::UniversalId::Type_Weapon) + { + type = CSMWorld::UniversalId::Type_Referenceable; + } + } + if (mDisplay == CSMWorld::TableMimeData::convertEnums(type)) + { + emit tableMimeDataDropped(mEditor, mIndexWrapper->mIndex, data[i], document); + emit editorDataCommited(mEditor, mIndexWrapper->mIndex, mDisplay); + break; } } } From 58daf52a675da61d87e9fee305e82aa4cf93d664 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 21 Mar 2014 12:44:06 +0100 Subject: [PATCH 088/127] deal with empty and invalid referenceable ID fields --- apps/opencs/view/render/previewwidget.cpp | 12 ++++++++++-- apps/opencs/view/world/previewsubview.cpp | 5 ++++- 2 files changed, 14 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp index 9b64cf6f4e..94cb7ce6eb 100644 --- a/apps/opencs/view/render/previewwidget.cpp +++ b/apps/opencs/view/render/previewwidget.cpp @@ -30,9 +30,16 @@ void CSVRender::PreviewWidget::setModel() { mObject.setNull(); - int column = mData.getReferenceables().findColumnIndex (CSMWorld::Columns::ColumnId_Model); + if (mReferenceableId.empty()) + return; - int row = mData.getReferenceables().getIndex (mReferenceableId); + int column = + mData.getReferenceables().findColumnIndex (CSMWorld::Columns::ColumnId_Model); + + int row = mData.getReferenceables().searchId (mReferenceableId); + + if (row==-1) + return; QVariant value = mData.getReferenceables().getData (row, column); @@ -142,6 +149,7 @@ void CSVRender::PreviewWidget::ReferenceDataChanged (const QModelIndex& topLeft, if (index.column()>=topLeft.column() && index.column()<=bottomRight.row()) { mReferenceableId = references.data (index).toString().toUtf8().constData(); + /// \todo update title setModel(); } diff --git a/apps/opencs/view/world/previewsubview.cpp b/apps/opencs/view/world/previewsubview.cpp index 587af561fb..769ff3ddce 100644 --- a/apps/opencs/view/world/previewsubview.cpp +++ b/apps/opencs/view/world/previewsubview.cpp @@ -21,7 +21,10 @@ CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDo std::string referenceableId = document.getData().getReferences().getRecord (id.getId()).get().mRefID; - setWindowTitle (("Preview: Reference to " + referenceableId).c_str()); + if (referenceableId.empty()) + setWindowTitle ("Preview: Reference to "); + else + setWindowTitle (("Preview: Reference to " + referenceableId).c_str()); mScene = new CSVRender::PreviewWidget (document.getData(), referenceableId, id.getId(), this); From 698fe8cce3208c54c682ee3ed19f2c757f80fc05 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 21 Mar 2014 12:52:46 +0100 Subject: [PATCH 089/127] update preview title on changed referenceableID (preview for references only) --- apps/opencs/view/render/previewwidget.cpp | 2 +- apps/opencs/view/render/previewwidget.hpp | 2 ++ apps/opencs/view/world/previewsubview.cpp | 15 +++++++++++---- apps/opencs/view/world/previewsubview.hpp | 2 ++ 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp index 94cb7ce6eb..3e70fd9990 100644 --- a/apps/opencs/view/render/previewwidget.cpp +++ b/apps/opencs/view/render/previewwidget.cpp @@ -149,7 +149,7 @@ void CSVRender::PreviewWidget::ReferenceDataChanged (const QModelIndex& topLeft, if (index.column()>=topLeft.column() && index.column()<=bottomRight.row()) { mReferenceableId = references.data (index).toString().toUtf8().constData(); - /// \todo update title + emit referenceableIdChanged (mReferenceableId); setModel(); } diff --git a/apps/opencs/view/render/previewwidget.hpp b/apps/opencs/view/render/previewwidget.hpp index 2b6517e715..7a63d8fb12 100644 --- a/apps/opencs/view/render/previewwidget.hpp +++ b/apps/opencs/view/render/previewwidget.hpp @@ -46,6 +46,8 @@ namespace CSVRender void closeRequest(); + void referenceableIdChanged (const std::string& id); + private slots: void ReferenceableDataChanged (const QModelIndex& topLeft, diff --git a/apps/opencs/view/world/previewsubview.cpp b/apps/opencs/view/world/previewsubview.cpp index 769ff3ddce..df9c3276cb 100644 --- a/apps/opencs/view/world/previewsubview.cpp +++ b/apps/opencs/view/world/previewsubview.cpp @@ -21,10 +21,7 @@ CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDo std::string referenceableId = document.getData().getReferences().getRecord (id.getId()).get().mRefID; - if (referenceableId.empty()) - setWindowTitle ("Preview: Reference to "); - else - setWindowTitle (("Preview: Reference to " + referenceableId).c_str()); + referenceableIdChanged (referenceableId); mScene = new CSVRender::PreviewWidget (document.getData(), referenceableId, id.getId(), this); @@ -45,6 +42,8 @@ CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDo setWidget (widget); connect (mScene, SIGNAL (closeRequest()), this, SLOT (closeRequest())); + connect (mScene, SIGNAL (referenceableIdChanged (const std::string&)), + this, SLOT (referenceableIdChanged (const std::string&))); } void CSVWorld::PreviewSubView::setEditLock (bool locked) {} @@ -52,4 +51,12 @@ void CSVWorld::PreviewSubView::setEditLock (bool locked) {} void CSVWorld::PreviewSubView::closeRequest() { deleteLater(); +} + +void CSVWorld::PreviewSubView::referenceableIdChanged (const std::string& id) +{ + if (id.empty()) + setWindowTitle ("Preview: Reference to "); + else + setWindowTitle (("Preview: Reference to " + id).c_str()); } \ No newline at end of file diff --git a/apps/opencs/view/world/previewsubview.hpp b/apps/opencs/view/world/previewsubview.hpp index e7a2a261ed..4ca25c3cbe 100644 --- a/apps/opencs/view/world/previewsubview.hpp +++ b/apps/opencs/view/world/previewsubview.hpp @@ -30,6 +30,8 @@ namespace CSVWorld private slots: void closeRequest(); + + void referenceableIdChanged (const std::string& id); }; } From 1e57d557172a99672a1a065f878738cf1439d047 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 21 Mar 2014 13:27:46 +0100 Subject: [PATCH 090/127] update/close on deletion of reference/referenceable --- apps/opencs/view/render/previewwidget.cpp | 36 +++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp index 3e70fd9990..be7f66016d 100644 --- a/apps/opencs/view/render/previewwidget.cpp +++ b/apps/opencs/view/render/previewwidget.cpp @@ -110,6 +110,9 @@ CSVRender::PreviewWidget::PreviewWidget (CSMWorld::Data& data, void CSVRender::PreviewWidget::ReferenceableDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { + if (mReferenceableId.empty()) + return; + CSMWorld::IdTable& referenceables = dynamic_cast ( *mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables)); @@ -127,12 +130,36 @@ void CSVRender::PreviewWidget::ReferenceableDataChanged (const QModelIndex& topL void CSVRender::PreviewWidget::ReferenceableAboutToBeRemoved (const QModelIndex& parent, int start, int end) { + if (mReferenceableId.empty()) + return; + CSMWorld::IdTable& referenceables = dynamic_cast ( + *mData.getTableModel (CSMWorld::UniversalId::Type_Referenceables)); + + QModelIndex index = referenceables.getModelIndex (mReferenceableId, 0); + + if (index.row()>=start && index.row()<=end) + { + if (mReferenceId.empty()) + { + // this is a preview for a referenceble + emit closeRequest(); + } + else + { + // this is a preview for a reference + mObject.setNull(); + flagAsModified(); + } + } } void CSVRender::PreviewWidget::ReferenceDataChanged (const QModelIndex& topLeft, const QModelIndex& bottomRight) { + if (mReferenceId.empty()) + return; + CSMWorld::IdTable& references = dynamic_cast ( *mData.getTableModel (CSMWorld::UniversalId::Type_References)); @@ -160,5 +187,14 @@ void CSVRender::PreviewWidget::ReferenceDataChanged (const QModelIndex& topLeft, void CSVRender::PreviewWidget::ReferenceAboutToBeRemoved (const QModelIndex& parent, int start, int end) { + if (mReferenceId.empty()) + return; + CSMWorld::IdTable& references = dynamic_cast ( + *mData.getTableModel (CSMWorld::UniversalId::Type_References)); + + QModelIndex index = references.getModelIndex (mReferenceId, 0); + + if (index.row()>=start && index.row()<=end) + emit closeRequest(); } From 41fd94b1604c65199776968f477b27109bd201e8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 21 Mar 2014 13:39:22 +0100 Subject: [PATCH 091/127] compensated for different coordinate systems --- apps/opencs/view/render/navigation1st.cpp | 2 +- apps/opencs/view/render/scenewidget.cpp | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/render/navigation1st.cpp b/apps/opencs/view/render/navigation1st.cpp index b892d3e3e7..91f88634af 100644 --- a/apps/opencs/view/render/navigation1st.cpp +++ b/apps/opencs/view/render/navigation1st.cpp @@ -10,7 +10,7 @@ CSVRender::Navigation1st::Navigation1st() : mCamera (0) {} bool CSVRender::Navigation1st::activate (Ogre::Camera *camera) { mCamera = camera; - mCamera->setFixedYawAxis (true); + mCamera->setFixedYawAxis (true, Ogre::Vector3::UNIT_Z); Ogre::Radian pitch = mCamera->getOrientation().getPitch(); diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 6b2ca85b5e..5a3c14b49c 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -49,6 +49,7 @@ namespace CSVRender mCamera->lookAt(0,0,0); mCamera->setNearClipDistance(0.1); mCamera->setFarClipDistance(30000); + mCamera->roll (Ogre::Degree (90)); QTimer *timer = new QTimer (this); From 317f1e0b63afca99acc1d1442c63db47719f17bb Mon Sep 17 00:00:00 2001 From: "Alexander \"Ace\" Olofsson" Date: Fri, 21 Mar 2014 13:44:01 +0100 Subject: [PATCH 092/127] Update dialoguesubview.cpp That doesn't work on Windows. (Are and/or allowed in C++ in any other compiler?) --- apps/opencs/view/world/dialoguesubview.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 3bd09bb50c..abdc331039 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -1,4 +1,3 @@ - #include "dialoguesubview.hpp" #include @@ -122,7 +121,7 @@ void CSVWorld::DialogueDelegateDispatcherProxy::tableMimeDataDropped(const std:: { QLineEdit* lineEdit = qobject_cast(mEditor); { - if (!lineEdit or !mIndexWrapper.get()) + if (!lineEdit || !mIndexWrapper.get()) { return; } @@ -687,4 +686,4 @@ void CSVWorld::DialogueSubView::viewRecord() if (params.first.getType()!=CSMWorld::UniversalId::Type_None) emit focusId (params.first, params.second); } -} \ No newline at end of file +} From 394284d0f839bf4c135e842534161c8505112c97 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 22 Mar 2014 00:46:47 +0100 Subject: [PATCH 093/127] Fixes #1209: Tarhiel never falls There are a few pitfalls with this code: - Gravity is only considered when applying queued movement. Therefore, make sure to queue some movement every frame. (Could be refactored in the future?) - The character controller never detects being in free fall (!World::isOnGround) unless movement has been applied. --- apps/openmw/mwmechanics/character.cpp | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 04d909b497..2db3bacf0e 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -1245,12 +1245,8 @@ void CharacterController::update(float duration) else //avoid z-rotating for knockdown world->rotateObject(mPtr, rot.x, rot.y, 0.0f, true); - // always control actual movement by animation unless this: - // FIXME: actor falling/landing should be controlled by physics engine - if(mMovementAnimVelocity == 0.0f && (vec.length() > 0.0f || mJumpState != JumpState_None)) - { + if (mMovementAnimVelocity == 0) world->queueMovement(mPtr, vec); - } } movement = vec; @@ -1290,7 +1286,7 @@ void CharacterController::update(float duration) } // Update movement - if(moved.squaredLength() > 1.0f) + if(mMovementAnimVelocity > 0) world->queueMovement(mPtr, moved); } mSkipAnim = false; From 0c207f7212a50ac8fa603054337ad2aa092963df Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 22 Mar 2014 01:06:43 +0100 Subject: [PATCH 094/127] Fix build error --- apps/opencs/view/render/previewwidget.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/opencs/view/render/previewwidget.cpp b/apps/opencs/view/render/previewwidget.cpp index 43d45f4cb9..1cd39c89b1 100644 --- a/apps/opencs/view/render/previewwidget.cpp +++ b/apps/opencs/view/render/previewwidget.cpp @@ -2,6 +2,7 @@ #include "previewwidget.hpp" #include +#include #include "../../model/world/data.hpp" From 6bd3b3ee78bb03af1901e75ccfe9209feb05ed66 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 22 Mar 2014 15:00:49 +0100 Subject: [PATCH 095/127] include local variable state in saved games --- apps/openmw/mwworld/livecellref.cpp | 10 +++++++++- apps/openmw/mwworld/refdata.cpp | 14 ++++++++++++-- apps/openmw/mwworld/refdata.hpp | 8 +++++--- 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/apps/openmw/mwworld/livecellref.cpp b/apps/openmw/mwworld/livecellref.cpp index d71704fd70..c15f63abe1 100644 --- a/apps/openmw/mwworld/livecellref.cpp +++ b/apps/openmw/mwworld/livecellref.cpp @@ -10,16 +10,24 @@ void MWWorld::LiveCellRefBase::loadImp (const ESM::ObjectState& state) { mRef = state.mRef; mData = RefData (state); + Ptr ptr (this); + + if (state.mHasLocals) + mData.setLocals (state.mLocals, mClass->getScript (ptr)); + mClass->readAdditionalState (ptr, state); } void MWWorld::LiveCellRefBase::saveImp (ESM::ObjectState& state) const { state.mRef = mRef; - mData.write (state); + /// \todo get rid of this cast once const-correct Ptr are available Ptr ptr (const_cast (this)); + + mData.write (state, mClass->getScript (ptr)); + mClass->writeAdditionalState (ptr, state); } diff --git a/apps/openmw/mwworld/refdata.cpp b/apps/openmw/mwworld/refdata.cpp index 8d48078b1d..907204739b 100644 --- a/apps/openmw/mwworld/refdata.cpp +++ b/apps/openmw/mwworld/refdata.cpp @@ -76,9 +76,13 @@ namespace MWWorld } } - void RefData::write (ESM::ObjectState& objectState) const + void RefData::write (ESM::ObjectState& objectState, const std::string& scriptId) const { - objectState.mHasLocals = false; + objectState.mHasLocals = mHasLocals; + + if (mHasLocals) + mLocals.write (objectState.mLocals, scriptId); + objectState.mEnabled = mEnabled; objectState.mCount = mCount; objectState.mPosition = mPosition; @@ -148,6 +152,12 @@ namespace MWWorld } } + void RefData::setLocals (const ESM::Locals& locals, const std::string& scriptId) + { + mHasLocals = true; + mLocals.read (locals, scriptId); + } + void RefData::setCount (int count) { if(count == 0) diff --git a/apps/openmw/mwworld/refdata.hpp b/apps/openmw/mwworld/refdata.hpp index 19e3d48822..a74eb838cf 100644 --- a/apps/openmw/mwworld/refdata.hpp +++ b/apps/openmw/mwworld/refdata.hpp @@ -64,9 +64,9 @@ namespace MWWorld ~RefData(); - void write (ESM::ObjectState& objectState) const; - ///< Ignores local variables and custom data (not enough context available here to - /// perform these operations). + void write (ESM::ObjectState& objectState, const std::string& scriptId = "") const; + ///< Ignores custom data (not enough context available here to + /// perform this operations). RefData& operator= (const RefData& refData); @@ -83,6 +83,8 @@ namespace MWWorld void setLocals (const ESM::Script& script); + void setLocals (const ESM::Locals& locals, const std::string& scriptId); + void setCount (int count); /// Set object count (an object pile is a simple object with a count >1). /// From 87ae03b5d4273b4358b67416ae97faa51ec57163 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 22 Mar 2014 16:39:24 +0100 Subject: [PATCH 096/127] fix for previous commit --- apps/openmw/mwworld/livecellref.cpp | 12 +++++++++++- apps/openmw/mwworld/refdata.cpp | 6 ------ apps/openmw/mwworld/refdata.hpp | 2 -- 3 files changed, 11 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwworld/livecellref.cpp b/apps/openmw/mwworld/livecellref.cpp index c15f63abe1..0fbb26c845 100644 --- a/apps/openmw/mwworld/livecellref.cpp +++ b/apps/openmw/mwworld/livecellref.cpp @@ -3,8 +3,12 @@ #include +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" + #include "ptr.hpp" #include "class.hpp" +#include "esmstore.hpp" void MWWorld::LiveCellRefBase::loadImp (const ESM::ObjectState& state) { @@ -14,7 +18,13 @@ void MWWorld::LiveCellRefBase::loadImp (const ESM::ObjectState& state) Ptr ptr (this); if (state.mHasLocals) - mData.setLocals (state.mLocals, mClass->getScript (ptr)); + { + std::string scriptId = mClass->getScript (ptr); + + mData.setLocals (*MWBase::Environment::get().getWorld()->getStore(). + get().search (scriptId)); + mData.getLocals().read (state.mLocals, scriptId); + } mClass->readAdditionalState (ptr, state); } diff --git a/apps/openmw/mwworld/refdata.cpp b/apps/openmw/mwworld/refdata.cpp index 907204739b..008782130b 100644 --- a/apps/openmw/mwworld/refdata.cpp +++ b/apps/openmw/mwworld/refdata.cpp @@ -152,12 +152,6 @@ namespace MWWorld } } - void RefData::setLocals (const ESM::Locals& locals, const std::string& scriptId) - { - mHasLocals = true; - mLocals.read (locals, scriptId); - } - void RefData::setCount (int count) { if(count == 0) diff --git a/apps/openmw/mwworld/refdata.hpp b/apps/openmw/mwworld/refdata.hpp index a74eb838cf..82371b056a 100644 --- a/apps/openmw/mwworld/refdata.hpp +++ b/apps/openmw/mwworld/refdata.hpp @@ -83,8 +83,6 @@ namespace MWWorld void setLocals (const ESM::Script& script); - void setLocals (const ESM::Locals& locals, const std::string& scriptId); - void setCount (int count); /// Set object count (an object pile is a simple object with a count >1). /// From 452b522bc3105b3aba95aeab86124ddc0839347e Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 22 Mar 2014 19:01:41 +0100 Subject: [PATCH 097/127] Fix typos --- components/compiler/lineparser.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/components/compiler/lineparser.cpp b/components/compiler/lineparser.cpp index 5457d76255..98bd63ba1e 100644 --- a/components/compiler/lineparser.cpp +++ b/components/compiler/lineparser.cpp @@ -86,7 +86,7 @@ namespace Compiler { if (mState==PotentialEndState) { - getErrorHandler().warning ("stay string argument (ignoring it)", loc); + getErrorHandler().warning ("stray string argument (ignoring it)", loc); mState = EndState; return true; } @@ -377,19 +377,19 @@ namespace Compiler case Scanner::K_else: - getErrorHandler().warning ("stay else (ignoring it)", loc); + getErrorHandler().warning ("stray else (ignoring it)", loc); mState = EndState; return true; case Scanner::K_endif: - getErrorHandler().warning ("stay endif (ignoring it)", loc); + getErrorHandler().warning ("stray endif (ignoring it)", loc); mState = EndState; return true; case Scanner::K_begin: - getErrorHandler().warning ("stay begin (ignoring it)", loc); + getErrorHandler().warning ("stray begin (ignoring it)", loc); mState = EndState; return true; } From 0a17245633a10d3583d684fa92a5ac0b61c0fa83 Mon Sep 17 00:00:00 2001 From: scrawl Date: Sat, 22 Mar 2014 19:02:14 +0100 Subject: [PATCH 098/127] Refactored settings window --- CMakeLists.txt | 1 + apps/openmw/mwgui/settingswindow.cpp | 380 +++++++++------------- apps/openmw/mwgui/settingswindow.hpp | 37 +-- apps/openmw/mwrender/water.cpp | 6 +- files/mygui/openmw_settings_window.layout | 170 ++++++++-- files/settings-default.cfg | 2 - 6 files changed, 295 insertions(+), 301 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index fb3827588b..392fdfc66c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,6 +132,7 @@ set(OENGINE_OGRE set(OENGINE_GUI ${LIBDIR}/openengine/gui/manager.cpp + ${LIBDIR}/openengine/gui/layout.hpp ) set(OENGINE_BULLET diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index c99e2d0de3..78adecd3ef 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -83,91 +83,116 @@ namespace } return false; } + + const char* checkButtonType = "CheckButton"; + const char* sliderType = "Slider"; + + std::string getSettingType(MyGUI::Widget* widget) + { + return widget->getUserString("SettingType"); + } + + std::string getSettingName(MyGUI::Widget* widget) + { + return widget->getUserString("SettingName"); + } + + std::string getSettingCategory(MyGUI::Widget* widget) + { + return widget->getUserString("SettingCategory"); + } + + std::string getSettingValueType(MyGUI::Widget* widget) + { + return widget->getUserString("SettingValueType"); + } + + void getSettingMinMax(MyGUI::Widget* widget, float& min, float& max) + { + const char* settingMin = "SettingMin"; + const char* settingMax = "SettingMax"; + min = 0.f; + max = 1.f; + if (!widget->getUserString(settingMin).empty()) + min = boost::lexical_cast(widget->getUserString(settingMin)); + if (!widget->getUserString(settingMax).empty()) + max = boost::lexical_cast(widget->getUserString(settingMax)); + } } namespace MWGui { + void SettingsWindow::configureWidgets(MyGUI::Widget* widget) + { + MyGUI::EnumeratorWidgetPtr widgets = widget->getEnumerator(); + while (widgets.next()) + { + MyGUI::Widget* current = widgets.current(); + + std::string type = getSettingType(current); + if (type == checkButtonType) + { + std::string initialValue = Settings::Manager::getBool(getSettingName(current), + getSettingCategory(current)) + ? "#{sOn}" : "#{sOff}"; + current->castType()->setCaptionWithReplacing(initialValue); + current->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); + } + if (type == sliderType) + { + MyGUI::ScrollBar* scroll = current->castType(); + if (getSettingValueType(current) == "Float") + { + // TODO: ScrollBar isn't meant for this. should probably use a dedicated FloatSlider widget + float min,max; + getSettingMinMax(scroll, min, max); + float value = Settings::Manager::getFloat(getSettingName(current), getSettingCategory(current)); + value = (value-min)/(max-min); + + scroll->setScrollPosition( value * (scroll->getScrollRange()-1)); + } + else + { + int value = Settings::Manager::getFloat(getSettingName(current), getSettingCategory(current)); + scroll->setScrollPosition(value); + } + scroll->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); + } + + configureWidgets(current); + } + } + SettingsWindow::SettingsWindow() : WindowBase("openmw_settings_window.layout") { + configureWidgets(mMainWidget); + getWidget(mOkButton, "OkButton"); - getWidget(mBestAttackButton, "BestAttackButton"); - getWidget(mGrabCursorButton, "GrabCursorButton"); - getWidget(mSubtitlesButton, "SubtitlesButton"); - getWidget(mCrosshairButton, "CrosshairButton"); getWidget(mResolutionList, "ResolutionList"); - getWidget(mMenuTransparencySlider, "MenuTransparencySlider"); - getWidget(mToolTipDelaySlider, "ToolTipDelaySlider"); - getWidget(mViewDistanceSlider, "ViewDistanceSlider"); getWidget(mFullscreenButton, "FullscreenButton"); getWidget(mVSyncButton, "VSyncButton"); getWidget(mFPSButton, "FPSButton"); getWidget(mFOVSlider, "FOVSlider"); - getWidget(mMasterVolumeSlider, "MasterVolume"); - getWidget(mVoiceVolumeSlider, "VoiceVolume"); - getWidget(mEffectsVolumeSlider, "EffectsVolume"); - getWidget(mFootstepsVolumeSlider, "FootstepsVolume"); - getWidget(mMusicVolumeSlider, "MusicVolume"); getWidget(mAnisotropySlider, "AnisotropySlider"); getWidget(mTextureFilteringButton, "TextureFilteringButton"); getWidget(mAnisotropyLabel, "AnisotropyLabel"); getWidget(mAnisotropyBox, "AnisotropyBox"); - getWidget(mWaterShaderButton, "WaterShaderButton"); - getWidget(mReflectObjectsButton, "ReflectObjectsButton"); - getWidget(mReflectActorsButton, "ReflectActorsButton"); - getWidget(mReflectTerrainButton, "ReflectTerrainButton"); getWidget(mShadersButton, "ShadersButton"); getWidget(mShaderModeButton, "ShaderModeButton"); getWidget(mShadowsEnabledButton, "ShadowsEnabledButton"); - getWidget(mShadowsLargeDistance, "ShadowsLargeDistance"); getWidget(mShadowsTextureSize, "ShadowsTextureSize"); - getWidget(mActorShadows, "ActorShadows"); - getWidget(mStaticsShadows, "StaticsShadows"); - getWidget(mMiscShadows, "MiscShadows"); - getWidget(mTerrainShadows, "TerrainShadows"); getWidget(mControlsBox, "ControlsBox"); getWidget(mResetControlsButton, "ResetControlsButton"); - getWidget(mInvertYButton, "InvertYButton"); - getWidget(mCameraSensitivitySlider, "CameraSensitivitySlider"); getWidget(mRefractionButton, "RefractionButton"); - mSubtitlesButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); - mCrosshairButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); - mBestAttackButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); - mGrabCursorButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); - mInvertYButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mOkButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onOkButtonClicked); - mShadersButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShadersToggled); mShaderModeButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onShaderModeToggled); - mFullscreenButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); - mWaterShaderButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); - mRefractionButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); - mReflectObjectsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); - mReflectTerrainButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); - mReflectActorsButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mTextureFilteringButton->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onTextureFilteringChanged); - mVSyncButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mFPSButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onFpsToggled); - mMenuTransparencySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); - mFOVSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); - mToolTipDelaySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); - mViewDistanceSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); mResolutionList->eventListChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onResolutionSelected); - mAnisotropySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); - mShadowsEnabledButton->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); - mShadowsLargeDistance->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); mShadowsTextureSize->eventComboChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onShadowTextureSizeChanged); - mActorShadows->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); - mStaticsShadows->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); - mMiscShadows->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); - mTerrainShadows->eventMouseButtonClick += MyGUI::newDelegate(this, &SettingsWindow::onButtonToggled); - - mMasterVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); - mVoiceVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); - mEffectsVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); - mFootstepsVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); - mMusicVolumeSlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); center(); @@ -194,73 +219,25 @@ namespace MWGui mResolutionList->addItem(str); } - // read settings - int menu_transparency = (mMenuTransparencySlider->getScrollRange()-1) * Settings::Manager::getFloat("menu transparency", "GUI"); - mMenuTransparencySlider->setScrollPosition(menu_transparency); - int tooltip_delay = (mToolTipDelaySlider->getScrollRange()-1) * Settings::Manager::getFloat("tooltip delay", "GUI"); - mToolTipDelaySlider->setScrollPosition(tooltip_delay); - - mSubtitlesButton->setCaptionWithReplacing(Settings::Manager::getBool("subtitles", "GUI") ? "#{sOn}" : "#{sOff}"); - mCrosshairButton->setCaptionWithReplacing(Settings::Manager::getBool("crosshair", "HUD") ? "#{sOn}" : "#{sOff}"); - mBestAttackButton->setCaptionWithReplacing(Settings::Manager::getBool("best attack", "Game") ? "#{sOn}" : "#{sOff}"); - mGrabCursorButton->setCaptionWithReplacing(Settings::Manager::getBool("grab cursor", "Input") ? "#{sOn}" : "#{sOff}"); - - float fovVal = (Settings::Manager::getFloat("field of view", "General")-sFovMin)/(sFovMax-sFovMin); - mFOVSlider->setScrollPosition(fovVal * (mFOVSlider->getScrollRange()-1)); - MyGUI::TextBox* fovText; - getWidget(fovText, "FovText"); - fovText->setCaption("Field of View (" + boost::lexical_cast(int(Settings::Manager::getFloat("field of view", "General"))) + ")"); - - float anisotropyVal = Settings::Manager::getInt("anisotropy", "General") / 16.0; - mAnisotropySlider->setScrollPosition(anisotropyVal * (mAnisotropySlider->getScrollRange()-1)); std::string tf = Settings::Manager::getString("texture filtering", "General"); mTextureFilteringButton->setCaption(textureFilteringToStr(tf)); mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast(Settings::Manager::getInt("anisotropy", "General")) + ")"); - float val = (Settings::Manager::getFloat("max viewing distance", "Viewing distance")-sViewDistMin)/(sViewDistMax-sViewDistMin); - int viewdist = (mViewDistanceSlider->getScrollRange()-1) * val; - mViewDistanceSlider->setScrollPosition(viewdist); - - mMasterVolumeSlider->setScrollPosition(Settings::Manager::getFloat("master volume", "Sound") * (mMasterVolumeSlider->getScrollRange()-1)); - mMusicVolumeSlider->setScrollPosition(Settings::Manager::getFloat("music volume", "Sound") * (mMusicVolumeSlider->getScrollRange()-1)); - mEffectsVolumeSlider->setScrollPosition(Settings::Manager::getFloat("sfx volume", "Sound") * (mEffectsVolumeSlider->getScrollRange()-1)); - mFootstepsVolumeSlider->setScrollPosition(Settings::Manager::getFloat("footsteps volume", "Sound") * (mFootstepsVolumeSlider->getScrollRange()-1)); - mVoiceVolumeSlider->setScrollPosition(Settings::Manager::getFloat("voice volume", "Sound") * (mVoiceVolumeSlider->getScrollRange()-1)); - - mWaterShaderButton->setCaptionWithReplacing(Settings::Manager::getBool("shader", "Water") ? "#{sOn}" : "#{sOff}"); - mReflectObjectsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect statics", "Water") ? "#{sOn}" : "#{sOff}"); - mReflectActorsButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect actors", "Water") ? "#{sOn}" : "#{sOff}"); - mReflectTerrainButton->setCaptionWithReplacing(Settings::Manager::getBool("reflect terrain", "Water") ? "#{sOn}" : "#{sOff}"); - mShadowsTextureSize->setCaption (Settings::Manager::getString ("texture size", "Shadows")); - mShadowsLargeDistance->setCaptionWithReplacing(Settings::Manager::getBool("split", "Shadows") ? "#{sOn}" : "#{sOff}"); - mShadowsEnabledButton->setCaptionWithReplacing(Settings::Manager::getBool("enabled", "Shadows") ? "#{sOn}" : "#{sOff}"); - mActorShadows->setCaptionWithReplacing(Settings::Manager::getBool("actor shadows", "Shadows") ? "#{sOn}" : "#{sOff}"); - mStaticsShadows->setCaptionWithReplacing(Settings::Manager::getBool("statics shadows", "Shadows") ? "#{sOn}" : "#{sOff}"); - mMiscShadows->setCaptionWithReplacing(Settings::Manager::getBool("misc shadows", "Shadows") ? "#{sOn}" : "#{sOff}"); - mTerrainShadows->setCaptionWithReplacing(Settings::Manager::getBool("terrain shadows", "Shadows") ? "#{sOn}" : "#{sOff}"); - - float cameraSens = (Settings::Manager::getFloat("camera sensitivity", "Input")-0.2)/(5.0-0.2); - mCameraSensitivitySlider->setScrollPosition (cameraSens * (mCameraSensitivitySlider->getScrollRange()-1)); - mCameraSensitivitySlider->eventScrollChangePosition += MyGUI::newDelegate(this, &SettingsWindow::onSliderChangePosition); - - mInvertYButton->setCaptionWithReplacing(Settings::Manager::getBool("invert y axis", "Input") ? "#{sOn}" : "#{sOff}"); - - mShadersButton->setCaptionWithReplacing (Settings::Manager::getBool("shaders", "Objects") ? "#{sOn}" : "#{sOff}"); mShaderModeButton->setCaption (Settings::Manager::getString("shader mode", "General")); - mRefractionButton->setCaptionWithReplacing (Settings::Manager::getBool("refraction", "Water") ? "#{sOn}" : "#{sOff}"); - if (!Settings::Manager::getBool("shaders", "Objects")) { mRefractionButton->setEnabled(false); mShadowsEnabledButton->setEnabled(false); } - mFullscreenButton->setCaptionWithReplacing(Settings::Manager::getBool("fullscreen", "Video") ? "#{sOn}" : "#{sOff}"); - mVSyncButton->setCaptionWithReplacing(Settings::Manager::getBool("vsync", "Video") ? "#{sOn}": "#{sOff}"); mFPSButton->setCaptionWithReplacing(fpsLevelToStr(Settings::Manager::getInt("fps", "HUD"))); + + MyGUI::TextBox* fovText; + getWidget(fovText, "FovText"); + fovText->setCaption("Field of View (" + boost::lexical_cast(int(Settings::Manager::getInt("field of view", "General"))) + ")"); } void SettingsWindow::onOkButtonClicked(MyGUI::Widget* _sender) @@ -320,6 +297,39 @@ namespace MWGui newState = true; } + if (_sender == mVSyncButton) + { + // Ogre::Window::setVSyncEnabled is bugged in 1.8 +#if OGRE_VERSION < (1 << 16 | 9 << 8 | 0) + MWBase::Environment::get().getWindowManager()-> + messageBox("VSync will be applied after a restart", std::vector()); +#endif + } + + if (_sender == mShadersButton) + { + if (newState == false) + { + // refraction needs shaders to display underwater fog + mRefractionButton->setCaptionWithReplacing("#{sOff}"); + mRefractionButton->setEnabled(false); + + Settings::Manager::setBool("refraction", "Water", false); + + // shadows not supported + mShadowsEnabledButton->setEnabled(false); + mShadowsEnabledButton->setCaptionWithReplacing("#{sOff}"); + Settings::Manager::setBool("enabled", "Shadows", false); + } + else + { + // re-enable + mRefractionButton->setEnabled(true); + + mShadowsEnabledButton->setEnabled(true); + } + } + if (_sender == mFullscreenButton) { // check if this resolution is supported in fullscreen @@ -341,64 +351,15 @@ namespace MWGui MWBase::Environment::get().getWindowManager()-> messageBox(msg); _sender->castType()->setCaption(off); - } - else - { - Settings::Manager::setBool("fullscreen", "Video", newState); - apply(); + return; } } - else if (_sender == mVSyncButton) + + if (getSettingType(_sender) == checkButtonType) { - Settings::Manager::setBool("vsync", "Video", newState); - // Ogre::Window::setVSyncEnabled is bugged in 1.8 -#if OGRE_VERSION < (1 << 16 | 9 << 8 | 0) - MWBase::Environment::get().getWindowManager()-> - messageBox("VSync will be applied after a restart", std::vector()); -#endif - apply(); - } - else - { - if (_sender == mVSyncButton) - Settings::Manager::setBool("vsync", "Video", newState); - if (_sender == mWaterShaderButton) - Settings::Manager::setBool("shader", "Water", newState); - else if (_sender == mRefractionButton) - Settings::Manager::setBool("refraction", "Water", newState); - else if (_sender == mReflectObjectsButton) - { - Settings::Manager::setBool("reflect misc", "Water", newState); - Settings::Manager::setBool("reflect statics", "Water", newState); - Settings::Manager::setBool("reflect statics small", "Water", newState); - } - else if (_sender == mReflectActorsButton) - Settings::Manager::setBool("reflect actors", "Water", newState); - else if (_sender == mReflectTerrainButton) - Settings::Manager::setBool("reflect terrain", "Water", newState); - else if (_sender == mShadowsEnabledButton) - Settings::Manager::setBool("enabled", "Shadows", newState); - else if (_sender == mShadowsLargeDistance) - Settings::Manager::setBool("split", "Shadows", newState); - else if (_sender == mActorShadows) - Settings::Manager::setBool("actor shadows", "Shadows", newState); - else if (_sender == mStaticsShadows) - Settings::Manager::setBool("statics shadows", "Shadows", newState); - else if (_sender == mMiscShadows) - Settings::Manager::setBool("misc shadows", "Shadows", newState); - else if (_sender == mTerrainShadows) - Settings::Manager::setBool("terrain shadows", "Shadows", newState); - else if (_sender == mInvertYButton) - Settings::Manager::setBool("invert y axis", "Input", newState); - else if (_sender == mCrosshairButton) - Settings::Manager::setBool("crosshair", "HUD", newState); - else if (_sender == mSubtitlesButton) - Settings::Manager::setBool("subtitles", "GUI", newState); - else if (_sender == mBestAttackButton) - Settings::Manager::setBool("best attack", "Game", newState); - else if (_sender == mGrabCursorButton) - Settings::Manager::setBool("grab cursor", "Input", newState); + Settings::Manager::setBool(getSettingName(_sender), getSettingCategory(_sender), newState); apply(); + return; } } @@ -419,50 +380,6 @@ namespace MWGui apply(); } - void SettingsWindow::onShadersToggled(MyGUI::Widget* _sender) - { - std::string on = MWBase::Environment::get().getWindowManager()->getGameSettingString("sOn", "On"); - std::string off = MWBase::Environment::get().getWindowManager()->getGameSettingString("sOff", "On"); - - std::string val = static_cast(_sender)->getCaption(); - if (val == off) - val = on; - else - val = off; - static_cast(_sender)->setCaptionWithReplacing (val); - - if (val == off) - { - Settings::Manager::setBool("shaders", "Objects", false); - - // refraction needs shaders to display underwater fog - mRefractionButton->setCaptionWithReplacing("#{sOff}"); - mRefractionButton->setEnabled(false); - - Settings::Manager::setBool("refraction", "Water", false); - Settings::Manager::setBool("underwater effect", "Water", false); - - // shadows not supported - mShadowsEnabledButton->setEnabled(false); - mShadowsEnabledButton->setCaptionWithReplacing("#{sOff}"); - Settings::Manager::setBool("enabled", "Shadows", false); - } - else - { - Settings::Manager::setBool("shaders", "Objects", true); - - // re-enable - mReflectObjectsButton->setEnabled(true); - mReflectActorsButton->setEnabled(true); - mReflectTerrainButton->setEnabled(true); - mRefractionButton->setEnabled(true); - - mShadowsEnabledButton->setEnabled(true); - } - - apply(); - } - void SettingsWindow::onFpsToggled(MyGUI::Widget* _sender) { int newLevel = (Settings::Manager::getInt("fps", "HUD") + 1) % 3; @@ -479,39 +396,34 @@ namespace MWGui void SettingsWindow::onSliderChangePosition(MyGUI::ScrollBar* scroller, size_t pos) { - float val = pos / float(scroller->getScrollRange()-1); - if (scroller == mMenuTransparencySlider) - Settings::Manager::setFloat("menu transparency", "GUI", val); - else if (scroller == mToolTipDelaySlider) - Settings::Manager::setFloat("tooltip delay", "GUI", val); - else if (scroller == mViewDistanceSlider) - Settings::Manager::setFloat("max viewing distance", "Viewing distance", (1-val) * sViewDistMin + val * sViewDistMax); - else if (scroller == mFOVSlider) + if (getSettingType(scroller) == "Slider") { - MyGUI::TextBox* fovText; - getWidget(fovText, "FovText"); - fovText->setCaption("Field of View (" + boost::lexical_cast(int((1-val) * sFovMin + val * sFovMax)) + ")"); - Settings::Manager::setFloat("field of view", "General", (1-val) * sFovMin + val * sFovMax); - } - else if (scroller == mAnisotropySlider) - { - mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast(int(val*16)) + ")"); - Settings::Manager::setInt("anisotropy", "General", val * 16); - } - else if (scroller == mMasterVolumeSlider) - Settings::Manager::setFloat("master volume", "Sound", val); - else if (scroller == mVoiceVolumeSlider) - Settings::Manager::setFloat("voice volume", "Sound", val); - else if (scroller == mEffectsVolumeSlider) - Settings::Manager::setFloat("sfx volume", "Sound", val); - else if (scroller == mFootstepsVolumeSlider) - Settings::Manager::setFloat("footsteps volume", "Sound", val); - else if (scroller == mMusicVolumeSlider) - Settings::Manager::setFloat("music volume", "Sound", val); - else if (scroller == mCameraSensitivitySlider) - Settings::Manager::setFloat("camera sensitivity", "Input", (1-val) * 0.2 + val * 5.f); + if (getSettingValueType(scroller) == "Float") + { + float value = pos / float(scroller->getScrollRange()-1); - apply(); + float min,max; + getSettingMinMax(scroller, min, max); + value = min + (max-min) * value; + Settings::Manager::setFloat(getSettingName(scroller), getSettingCategory(scroller), value); + + if (scroller == mFOVSlider) + { + MyGUI::TextBox* fovText; + getWidget(fovText, "FovText"); + fovText->setCaption("Field of View (" + boost::lexical_cast(int(value)) + ")"); + } + } + else + { + Settings::Manager::setInt(getSettingName(scroller), getSettingCategory(scroller), pos); + if (scroller == mAnisotropySlider) + { + mAnisotropyLabel->setCaption("Anisotropy (" + boost::lexical_cast(pos) + ")"); + } + } + apply(); + } } void SettingsWindow::apply() diff --git a/apps/openmw/mwgui/settingswindow.hpp b/apps/openmw/mwgui/settingswindow.hpp index 6b9ce414b8..7a6c1a5ed5 100644 --- a/apps/openmw/mwgui/settingswindow.hpp +++ b/apps/openmw/mwgui/settingswindow.hpp @@ -19,61 +19,29 @@ namespace MWGui void updateControlsBox(); - private: - static int const sFovMin = 30; - static int const sFovMax = 140; - static int const sViewDistMin = 2000; - static int const sViewDistMax = 5600; - - protected: + protected: MyGUI::Button* mOkButton; - MyGUI::ScrollBar* mMenuTransparencySlider; - MyGUI::ScrollBar* mToolTipDelaySlider; - MyGUI::Button* mSubtitlesButton; - MyGUI::Button* mCrosshairButton; - MyGUI::Button* mBestAttackButton; - MyGUI::Button* mGrabCursorButton; - // graphics MyGUI::ListBox* mResolutionList; MyGUI::Button* mFullscreenButton; MyGUI::Button* mVSyncButton; MyGUI::Button* mFPSButton; - MyGUI::ScrollBar* mViewDistanceSlider; MyGUI::ScrollBar* mFOVSlider; MyGUI::ScrollBar* mAnisotropySlider; MyGUI::ComboBox* mTextureFilteringButton; MyGUI::TextBox* mAnisotropyLabel; MyGUI::Widget* mAnisotropyBox; - MyGUI::Button* mWaterShaderButton; - MyGUI::Button* mReflectObjectsButton; - MyGUI::Button* mReflectActorsButton; - MyGUI::Button* mReflectTerrainButton; MyGUI::Button* mShadersButton; MyGUI::Button* mShaderModeButton; MyGUI::Button* mRefractionButton; MyGUI::Button* mShadowsEnabledButton; - MyGUI::Button* mShadowsLargeDistance; MyGUI::ComboBox* mShadowsTextureSize; - MyGUI::Button* mActorShadows; - MyGUI::Button* mStaticsShadows; - MyGUI::Button* mMiscShadows; - MyGUI::Button* mTerrainShadows; - - // audio - MyGUI::ScrollBar* mMasterVolumeSlider; - MyGUI::ScrollBar* mVoiceVolumeSlider; - MyGUI::ScrollBar* mEffectsVolumeSlider; - MyGUI::ScrollBar* mFootstepsVolumeSlider; - MyGUI::ScrollBar* mMusicVolumeSlider; // controls MyGUI::ScrollView* mControlsBox; MyGUI::Button* mResetControlsButton; - MyGUI::Button* mInvertYButton; - MyGUI::ScrollBar* mCameraSensitivitySlider; void onOkButtonClicked(MyGUI::Widget* _sender); void onFpsToggled(MyGUI::Widget* _sender); @@ -84,7 +52,6 @@ namespace MWGui void onResolutionAccept(); void onResolutionCancel(); - void onShadersToggled(MyGUI::Widget* _sender); void onShaderModeToggled(MyGUI::Widget* _sender); void onShadowTextureSizeChanged(MyGUI::ComboBox* _sender, size_t pos); @@ -94,6 +61,8 @@ namespace MWGui void onResetDefaultBindingsAccept (); void apply(); + + void configureWidgets(MyGUI::Widget* widget); }; } diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 1fa5d88341..5368cbe687 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -418,10 +418,8 @@ void Water::applyRTT() void Water::applyVisibilityMask() { mVisibilityFlags = RV_Terrain * Settings::Manager::getBool("reflect terrain", "Water") - + RV_Statics * Settings::Manager::getBool("reflect statics", "Water") - + RV_StaticsSmall * Settings::Manager::getBool("reflect small statics", "Water") + + (RV_Statics + RV_StaticsSmall + RV_Misc) * Settings::Manager::getBool("reflect statics", "Water") + RV_Actors * Settings::Manager::getBool("reflect actors", "Water") - + RV_Misc * Settings::Manager::getBool("reflect misc", "Water") + RV_Sky; if (mReflection) @@ -444,8 +442,6 @@ void Water::processChangedSettings(const Settings::CategorySettingVector& settin if ( it->first == "Water" && ( it->second == "reflect actors" || it->second == "reflect terrain" - || it->second == "reflect misc" - || it->second == "reflect small statics" || it->second == "reflect statics")) applyVisMask = true; } diff --git a/files/mygui/openmw_settings_window.layout b/files/mygui/openmw_settings_window.layout index 61103963db..adf9f1557f 100644 --- a/files/mygui/openmw_settings_window.layout +++ b/files/mygui/openmw_settings_window.layout @@ -18,6 +18,10 @@ + + + + @@ -34,6 +38,10 @@ + + + + @@ -45,28 +53,44 @@ - + + + + + - + + + + + - + + + + + - + + + + + @@ -81,6 +105,10 @@ + + + + @@ -89,6 +117,10 @@ + + + + @@ -97,6 +129,10 @@ + + + + @@ -105,6 +141,10 @@ + + + + @@ -113,6 +153,10 @@ + + + + @@ -127,7 +171,11 @@ - + + + + + @@ -139,6 +187,12 @@ + + + + + + @@ -149,8 +203,6 @@ - - @@ -163,16 +215,23 @@ - - + + + + + - + + + + + @@ -186,7 +245,11 @@ - + + + + + @@ -205,6 +268,12 @@ + + + + + + @@ -233,8 +302,10 @@ - - + + + + @@ -244,6 +315,12 @@ + + + + + + @@ -260,7 +337,11 @@ - + + + + + @@ -269,21 +350,33 @@ - + + + + + - + + + + + - + + + + + @@ -291,7 +384,11 @@ - + + + + + @@ -302,7 +399,11 @@ - + + + + + @@ -311,35 +412,52 @@ - + + + + + - - - + + + + - + + + + + - + + + + + - + + + + + diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 4fb7097f84..5dfc054553 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -137,9 +137,7 @@ refraction = true rtt size = 512 reflect terrain = true reflect statics = false -reflect small statics = false reflect actors = false -reflect misc = false [Sound] # Device name. Blank means default From 772a49b2a641b2f3dc0f9a10408d58b85cc85ddd Mon Sep 17 00:00:00 2001 From: cc9cii Date: Sun, 23 Mar 2014 13:24:04 +1100 Subject: [PATCH 099/127] Just some notes for future maintenance. --- apps/openmw/mwworld/physicssystem.cpp | 102 +++++++++++++++++++++++--- 1 file changed, 91 insertions(+), 11 deletions(-) diff --git a/apps/openmw/mwworld/physicssystem.cpp b/apps/openmw/mwworld/physicssystem.cpp index 3c0c3ffaa3..c2d902d697 100644 --- a/apps/openmw/mwworld/physicssystem.cpp +++ b/apps/openmw/mwworld/physicssystem.cpp @@ -50,25 +50,102 @@ namespace MWWorld const Ogre::Vector3 &velocity, float &remainingTime, OEngine::Physic::PhysicEngine *engine) { + /* + * Slide up an incline or set of stairs. Should be called only after a + * collision detection otherwise unnecessary tracing will be performed. + * + * NOTE: with a small change this method can be used to step over an obstacle + * of height sStepSize. + * + * If successful return 'true' and update 'position' to the new possible + * location and adjust 'remainingTime'. + * + * If not successful return 'false'. May fail for these reasons: + * - can't move directly up from current position + * - having moved up by between epsilon() and sStepSize, can't move forward + * - having moved forward by between epsilon() and velocity*remainingTime, + * = moved down between 0 and just under sStepSize but slope was too steep, or + * = moved the full sStepSize down (FIXME: this could be a bug) + * + * + * + * Starting position. Obstacle or stairs with height upto sStepSize in front. + * + * +--+ +--+ |XX + * | | -------> velocity | | +--+XX + * | | | | |XXXXX + * | | +--+ | | +--+XXXXX + * | | |XX| | | |XXXXXXXX + * +--+ +--+ +--+ +-------- + * ============================================== + */ + + /* + * Try moving up sStepSize using stepper. + * FIXME: does not work in case there is no front obstacle but there is one above + * + * +--+ +--+ + * | | | | + * | | | | |XX + * | | | | +--+XX + * | | | | |XXXXX + * +--+ +--+ +--+ +--+XXXXX + * |XX| |XXXXXXXX + * +--+ +-------- + * ============================================== + */ OEngine::Physic::ActorTracer tracer, stepper; stepper.doTrace(colobj, position, position+Ogre::Vector3(0.0f,0.0f,sStepSize), engine); if(stepper.mFraction < std::numeric_limits::epsilon()) - return false; + return false; // didn't even move the smallest representable amount + // (TODO: shouldn't this be larger? Why bother with such a small amount?) + /* + * Try moving from the elevated position using tracer. + * + * +--+ +--+ + * | | |YY| FIXME: collision with object YY + * | | +--+ + * | | + * <------------------->| | + * +--+ +--+ + * |XX| the moved amount is velocity*remainingTime*tracer.mFraction + * +--+ + * ============================================== + */ tracer.doTrace(colobj, stepper.mEndPos, stepper.mEndPos + velocity*remainingTime, engine); if(tracer.mFraction < std::numeric_limits::epsilon()) - return false; + return false; // didn't even move the smallest representable amount + /* + * Try moving back down sStepSize using stepper. + * NOTE: if there is an obstacle below (e.g. stairs), we'll be "stepping up". + * Below diagram is the case where we "stepped over" an obstacle in front. + * + * +--+ + * |YY| + * +--+ +--+ + * | | + * | | + * +--+ | | + * |XX| | | + * +--+ +--+ + * ============================================== + */ stepper.doTrace(colobj, tracer.mEndPos, tracer.mEndPos-Ogre::Vector3(0.0f,0.0f,sStepSize), engine); if(stepper.mFraction < 1.0f && getSlope(stepper.mPlaneNormal) <= sMaxSlope) { // only step down onto semi-horizontal surfaces. don't step down onto the side of a house or a wall. + // TODO: stepper.mPlaneNormal does not appear to be reliable - needs more testing + // NOTE: caller's variables 'position' & 'remainingTime' are modified here position = stepper.mEndPos; - remainingTime *= (1.0f-tracer.mFraction); + remainingTime *= (1.0f-tracer.mFraction); // remaining time is proportional to remaining distance return true; } + // moved between 0 and just under sStepSize distance but slope was too great, + // or moved full sStepSize distance (FIXME: is this a bug?) return false; } @@ -164,26 +241,27 @@ namespace MWWorld { velocity = Ogre::Quaternion(Ogre::Radian(refpos.rot[2]), Ogre::Vector3::NEGATIVE_UNIT_Z) * movement; // not in water nor can fly, so need to deal with gravity - if(!physicActor->getOnGround()) + if(!physicActor->getOnGround()) // if current OnGround status is false, must be falling or jumping { // If falling, add part of the incoming velocity with the current inertia + // TODO: but we could be jumping up? velocity = velocity * time + physicActor->getInertialForce(); } - inertia = velocity; // REM velocity is for z axis only in this code block + inertia = velocity; // NOTE: velocity is for z axis only in this code block - if(!(movement.z > 0.0f)) + if(!(movement.z > 0.0f)) // falling or moving horizontally (or stationary?) check if we're on ground now { - wasOnGround = physicActor->getOnGround(); - // TODO: Find out if there is a significance with the value 2 used here - tracer.doTrace(colobj, position, position - Ogre::Vector3(0,0,2), engine); + wasOnGround = physicActor->getOnGround(); // store current state + tracer.doTrace(colobj, position, position - Ogre::Vector3(0,0,2), engine); // check if down 2 possible if(tracer.mFraction < 1.0f && getSlope(tracer.mPlaneNormal) <= sMaxSlope) isOnGround = true; } } + // NOTE: isOnGround was initialised false, so should stay false if falling or sliding horizontally if(isOnGround) { - // if we're on the ground, don't try to fall + // if we're on the ground, don't try to fall any more velocity.z = std::max(0.0f, velocity.z); // NOTE: two different velocity assignments above } @@ -196,6 +274,7 @@ namespace MWWorld float remainingTime = time; for(int iterations = 0; iterations < sMaxIterations && remainingTime > 0.01f; ++iterations) { + // NOTE: velocity is either z axis only or x & z axis Ogre::Vector3 nextpos = newPosition + velocity * remainingTime; // If not able to fly, walk or bipedal don't allow to move out of water @@ -229,8 +308,9 @@ namespace MWWorld break; } - // We hit something. Try to step up onto it. + // We hit something. Try to step up onto it. (NOTE: stepMove does not allow stepping over) // NOTE: May need to stop slaughterfish step out of the water. + // NOTE: stepMove may modify newPosition if((canWalk || isBipedal || isNpc) && stepMove(colobj, newPosition, velocity, remainingTime, engine)) isOnGround = !(newPosition.z < waterlevel || isFlying); // Only on the ground if there's gravity else From 205354ba30d18bc711ee5d9e106b9f5f447b468c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 23 Mar 2014 13:40:56 +0100 Subject: [PATCH 100/127] some ambient light cleanup --- apps/opencs/view/render/scenewidget.cpp | 8 ++------ apps/opencs/view/render/scenewidget.hpp | 6 +++--- apps/opencs/view/render/unpagedworldspacewidget.cpp | 2 +- 3 files changed, 6 insertions(+), 10 deletions(-) diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 5a3c14b49c..c59c142fc9 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -32,11 +32,7 @@ namespace CSVRender mSceneMgr = Ogre::Root::getSingleton().createSceneManager(Ogre::ST_GENERIC); - // Throw in a random color just to make sure multiple scenes work - Ogre::Real r = Ogre::Math::RangeRandom(0, 1); - Ogre::Real g = Ogre::Math::RangeRandom(0, 1); - Ogre::Real b = Ogre::Math::RangeRandom(0, 1); - mSceneMgr->setAmbientLight(Ogre::ColourValue(r,g,b,1)); + mSceneMgr->setAmbientLight (Ogre::ColourValue (0,0,0,1)); Ogre::Light* l = mSceneMgr->createLight(); l->setType (Ogre::Light::LT_DIRECTIONAL); @@ -57,7 +53,7 @@ namespace CSVRender timer->start (20); /// \todo make this configurable } - void SceneWidget::setAmbient (const Ogre::ColourValue& colour) + void SceneWidget::setDefaultAmbient (const Ogre::ColourValue& colour) { mSceneMgr->setAmbientLight (colour); } diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 375c877d22..51d3464edb 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -26,9 +26,6 @@ namespace CSVRender QPaintEngine* paintEngine() const; - void setAmbient (const Ogre::ColourValue& colour); - ///< \note The actual ambient colour may differ based on lighting settings. - protected: void setNavigation (Navigation *navigation); @@ -38,6 +35,9 @@ namespace CSVRender void flagAsModified(); + void setDefaultAmbient (const Ogre::ColourValue& colour); + ///< \note The actual ambient colour may differ based on lighting settings. + private: void paintEvent(QPaintEvent* e); void resizeEvent(QResizeEvent* e); diff --git a/apps/opencs/view/render/unpagedworldspacewidget.cpp b/apps/opencs/view/render/unpagedworldspacewidget.cpp index c7edbe79b1..fb74788cc2 100644 --- a/apps/opencs/view/render/unpagedworldspacewidget.cpp +++ b/apps/opencs/view/render/unpagedworldspacewidget.cpp @@ -15,7 +15,7 @@ void CSVRender::UnpagedWorldspaceWidget::update() Ogre::ColourValue colour; colour.setAsABGR (record.get().mAmbi.mAmbient); - setAmbient (colour); + setDefaultAmbient (colour); /// \todo deal with mSunlight and mFog/mForDensity } From d5506172e873836939495aae2805bf2472ec95c4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 23 Mar 2014 15:14:26 +0100 Subject: [PATCH 101/127] added lighting switching --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/render/lighting.cpp | 4 ++ apps/opencs/view/render/lighting.hpp | 27 +++++++++++++ apps/opencs/view/render/scenewidget.cpp | 40 +++++++++++++++++++- apps/opencs/view/render/scenewidget.hpp | 22 ++++++++++- apps/opencs/view/render/worldspacewidget.hpp | 2 +- apps/opencs/view/world/previewsubview.cpp | 8 ++-- apps/opencs/view/world/scenesubview.cpp | 7 +++- 8 files changed, 102 insertions(+), 10 deletions(-) create mode 100644 apps/opencs/view/render/lighting.cpp create mode 100644 apps/opencs/view/render/lighting.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index b2b534031b..ee7887f3ef 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -69,7 +69,7 @@ opencs_units (view/render ) opencs_units_noqt (view/render - navigation navigation1st navigationfree navigationorbit + navigation navigation1st navigationfree navigationorbit lighting ) opencs_units_noqt (view/world diff --git a/apps/opencs/view/render/lighting.cpp b/apps/opencs/view/render/lighting.cpp new file mode 100644 index 0000000000..d57570d695 --- /dev/null +++ b/apps/opencs/view/render/lighting.cpp @@ -0,0 +1,4 @@ + +#include "lighting.hpp" + +CSVRender::Lighting::~Lighting() {} \ No newline at end of file diff --git a/apps/opencs/view/render/lighting.hpp b/apps/opencs/view/render/lighting.hpp new file mode 100644 index 0000000000..a1da9f7e38 --- /dev/null +++ b/apps/opencs/view/render/lighting.hpp @@ -0,0 +1,27 @@ +#ifndef OPENCS_VIEW_LIGHTING_H +#define OPENCS_VIEW_LIGHTING_H + +namespace Ogre +{ + class SceneManager; + class ColourValue; +} + +namespace CSVRender +{ + class Lighting + { + public: + + virtual ~Lighting(); + + virtual void activate (Ogre::SceneManager *sceneManager, + const Ogre::ColourValue *defaultAmbient = 0) = 0; + + virtual void deactivate() = 0; + + virtual void setDefaultAmbient (const Ogre::ColourValue& colour) = 0; + }; +} + +#endif diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index c59c142fc9..8a1db1da06 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -11,7 +11,10 @@ #include #include +#include "../world/scenetoolmode.hpp" + #include "navigation.hpp" +#include "lighting.hpp" namespace CSVRender { @@ -19,11 +22,12 @@ namespace CSVRender : QWidget(parent) , mWindow(NULL) , mCamera(NULL) - , mSceneMgr(NULL), mNavigation (0), mUpdate (false) + , mSceneMgr(NULL), mNavigation (0), mLighting (0), mUpdate (false) , mKeyForward (false), mKeyBackward (false), mKeyLeft (false), mKeyRight (false) , mKeyRollLeft (false), mKeyRollRight (false) , mFast (false), mDragging (false), mMod1 (false) , mFastFactor (4) /// \todo make this configurable + , mDefaultAmbient (0, 0, 0, 0), mHasDefaultAmbient (false) { setAttribute(Qt::WA_PaintOnScreen); setAttribute(Qt::WA_NoSystemBackground); @@ -53,9 +57,27 @@ namespace CSVRender timer->start (20); /// \todo make this configurable } + CSVWorld::SceneToolMode *SceneWidget::makeLightingSelector (CSVWorld::SceneToolbar *parent) + { + CSVWorld::SceneToolMode *tool = new CSVWorld::SceneToolMode (parent); + + tool->addButton (":door.png", "day"); /// \todo replace icons + tool->addButton (":GMST.png", "night"); + tool->addButton (":Info.png", "bright"); + + connect (tool, SIGNAL (modeChanged (const std::string&)), + this, SLOT (selectLightingMode (const std::string&))); + + return tool; + } + void SceneWidget::setDefaultAmbient (const Ogre::ColourValue& colour) { - mSceneMgr->setAmbientLight (colour); + mDefaultAmbient = colour; + mHasDefaultAmbient = true; + + if (mLighting) + mLighting->setDefaultAmbient (colour); } void SceneWidget::updateOgreWindow() @@ -312,4 +334,18 @@ namespace CSVRender { return mFast ? mFastFactor : 1; } + + void SceneWidget::setLighting (Lighting *lighting) + { + if (mLighting) + mLighting->deactivate(); + + mLighting = lighting; + mLighting->activate (mSceneManager, mHasDefaultAmbient ? &mDefaultAmbient : 0); + } + + void SceneWidget::selectLightingMode (const std::string& mode) + { + + } } diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 51d3464edb..5058fb860c 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -3,17 +3,25 @@ #include +#include + namespace Ogre { class Camera; class SceneManager; class RenderWindow; - class ColourValue; +} + +namespace CSVWorld +{ + class SceneToolMode; + class SceneToolbar; } namespace CSVRender { class Navigation; + class Lighting; class SceneWidget : public QWidget { @@ -26,6 +34,10 @@ namespace CSVRender QPaintEngine* paintEngine() const; + CSVWorld::SceneToolMode *makeLightingSelector (CSVWorld::SceneToolbar *parent); + ///< \attention The created tool is not added to the toolbar (via addTool). Doing that + /// is the responsibility of the calling function. + protected: void setNavigation (Navigation *navigation); @@ -61,11 +73,15 @@ namespace CSVRender int getFastFactor() const; + void setLighting (Lighting *lighting); + ///< \attention The ownership of \a lighting is not transferred to *this. + Ogre::Camera* mCamera; Ogre::SceneManager* mSceneMgr; Ogre::RenderWindow* mWindow; Navigation *mNavigation; + Lighting *mLighting; bool mUpdate; bool mKeyForward; bool mKeyBackward; @@ -78,10 +94,14 @@ namespace CSVRender bool mMod1; QPoint mOldPos; int mFastFactor; + Ogre::ColourValue mDefaultAmbient; + bool mHasDefaultAmbient; private slots: void update(); + + void selectLightingMode (const std::string& mode); }; } diff --git a/apps/opencs/view/render/worldspacewidget.hpp b/apps/opencs/view/render/worldspacewidget.hpp index 2eccca3bf4..7921c3560c 100644 --- a/apps/opencs/view/render/worldspacewidget.hpp +++ b/apps/opencs/view/render/worldspacewidget.hpp @@ -28,7 +28,7 @@ namespace CSVRender WorldspaceWidget (QWidget *parent = 0); CSVWorld::SceneToolMode *makeNavigationSelector (CSVWorld::SceneToolbar *parent); - ///< \important The created tool is not added to the toolbar (via addTool). Doing that + ///< \attention The created tool is not added to the toolbar (via addTool). Doing that /// is the responsibility of the calling function. void selectDefaultNavigationMode(); diff --git a/apps/opencs/view/world/previewsubview.cpp b/apps/opencs/view/world/previewsubview.cpp index df9c3276cb..ac9776d222 100644 --- a/apps/opencs/view/world/previewsubview.cpp +++ b/apps/opencs/view/world/previewsubview.cpp @@ -3,11 +3,10 @@ #include -#include "../render/scenewidget.hpp" +#include "../render/previewwidget.hpp" #include "scenetoolbar.hpp" - -#include "../render/previewwidget.hpp" +#include "scenetoolmode.hpp" CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDoc::Document& document) : SubView (id) @@ -31,6 +30,9 @@ CSVWorld::PreviewSubView::PreviewSubView (const CSMWorld::UniversalId& id, CSMDo SceneToolbar *toolbar = new SceneToolbar (48, this); + SceneToolMode *lightingTool = mScene->makeLightingSelector (toolbar); + toolbar->addTool (lightingTool); + layout->addWidget (toolbar, 0); layout->addWidget (mScene, 1); diff --git a/apps/opencs/view/world/scenesubview.cpp b/apps/opencs/view/world/scenesubview.cpp index 66e0266046..10e8b40715 100644 --- a/apps/opencs/view/world/scenesubview.cpp +++ b/apps/opencs/view/world/scenesubview.cpp @@ -39,8 +39,11 @@ CSVWorld::SceneSubView::SceneSubView (const CSMWorld::UniversalId& id, CSMDoc::D else mScene = new CSVRender::UnpagedWorldspaceWidget (id.getId(), document, this); - SceneToolMode *tool = mScene->makeNavigationSelector (toolbar); - toolbar->addTool (tool); + SceneToolMode *navigationTool = mScene->makeNavigationSelector (toolbar); + toolbar->addTool (navigationTool); + + SceneToolMode *lightingTool = mScene->makeLightingSelector (toolbar); + toolbar->addTool (lightingTool); layout2->addWidget (toolbar, 0); From 235dbdf18ef66678bd1ccae9aefc6d2ba4b41ed5 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 26 Mar 2014 17:07:43 +0100 Subject: [PATCH 102/127] updated credits file --- credits.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/credits.txt b/credits.txt index 28a30e907e..7d2a5ca42f 100644 --- a/credits.txt +++ b/credits.txt @@ -21,6 +21,7 @@ athile Britt Mathis (galdor557) BrotherBrick cc9cii +Chris Boyce (slothlife) Chris Robinson (KittyCat) Cory F. Cohen (cfcohen) Cris Mihalache (Mirceam) From fa29942b27bc44c0f3e9ce8c97f250541d66d3b7 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 26 Mar 2014 17:47:56 +0100 Subject: [PATCH 103/127] added day lighting mode --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/render/lightingday.cpp | 36 +++++++++++++++++++++++++ apps/opencs/view/render/lightingday.hpp | 31 +++++++++++++++++++++ apps/opencs/view/render/scenewidget.cpp | 19 +++++++------ apps/opencs/view/render/scenewidget.hpp | 3 +++ 5 files changed, 80 insertions(+), 11 deletions(-) create mode 100644 apps/opencs/view/render/lightingday.cpp create mode 100644 apps/opencs/view/render/lightingday.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index ee7887f3ef..608f01d12c 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -69,7 +69,7 @@ opencs_units (view/render ) opencs_units_noqt (view/render - navigation navigation1st navigationfree navigationorbit lighting + navigation navigation1st navigationfree navigationorbit lighting lightingday ) opencs_units_noqt (view/world diff --git a/apps/opencs/view/render/lightingday.cpp b/apps/opencs/view/render/lightingday.cpp new file mode 100644 index 0000000000..ab0257c0c7 --- /dev/null +++ b/apps/opencs/view/render/lightingday.cpp @@ -0,0 +1,36 @@ + +#include "lightingday.hpp" + +#include + +CSVRender::LightingDay::LightingDay() : mSceneManager (0), mLight (0) {} + +void CSVRender::LightingDay::activate (Ogre::SceneManager *sceneManager, + const Ogre::ColourValue *defaultAmbient) +{ + mSceneManager = sceneManager; + + if (defaultAmbient) + mSceneManager->setAmbientLight (*defaultAmbient); + else + mSceneManager->setAmbientLight (Ogre::ColourValue (0.7, 0.7, 0.7, 1)); + + mLight = mSceneManager->createLight(); + mLight->setType (Ogre::Light::LT_DIRECTIONAL); + mLight->setDirection (Ogre::Vector3 (0, 0, -1)); + mLight->setDiffuseColour (Ogre::ColourValue (1, 1, 1)); +} + +void CSVRender::LightingDay::deactivate() +{ + if (mLight) + { + mSceneManager->destroyLight (mLight); + mLight = 0; + } +} + +void CSVRender::LightingDay::setDefaultAmbient (const Ogre::ColourValue& colour) +{ + mSceneManager->setAmbientLight (colour); +} \ No newline at end of file diff --git a/apps/opencs/view/render/lightingday.hpp b/apps/opencs/view/render/lightingday.hpp new file mode 100644 index 0000000000..8638146e23 --- /dev/null +++ b/apps/opencs/view/render/lightingday.hpp @@ -0,0 +1,31 @@ +#ifndef OPENCS_VIEW_LIGHTING_DAY_H +#define OPENCS_VIEW_LIGHTING_DAY_H + +#include "lighting.hpp" + +namespace Ogre +{ + class Light; +} + +namespace CSVRender +{ + class LightingDay : public Lighting + { + Ogre::SceneManager *mSceneManager; + Ogre::Light *mLight; + + public: + + LightingDay(); + + virtual void activate (Ogre::SceneManager *sceneManager, + const Ogre::ColourValue *defaultAmbient = 0); + + virtual void deactivate(); + + virtual void setDefaultAmbient (const Ogre::ColourValue& colour); + }; +} + +#endif diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 8a1db1da06..77d9ea1e07 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -38,19 +38,16 @@ namespace CSVRender mSceneMgr->setAmbientLight (Ogre::ColourValue (0,0,0,1)); - Ogre::Light* l = mSceneMgr->createLight(); - l->setType (Ogre::Light::LT_DIRECTIONAL); - l->setDirection (Ogre::Vector3(-0.4, -0.7, 0.3)); - l->setDiffuseColour (Ogre::ColourValue(0.7,0.7,0.7)); - mCamera = mSceneMgr->createCamera("foo"); - mCamera->setPosition(300,0,000); - mCamera->lookAt(0,0,0); - mCamera->setNearClipDistance(0.1); - mCamera->setFarClipDistance(30000); + mCamera->setPosition (300, 0, 0); + mCamera->lookAt (0, 0, 0); + mCamera->setNearClipDistance (0.1); + mCamera->setFarClipDistance (30000); mCamera->roll (Ogre::Degree (90)); + setLighting (&mLightingDay); + QTimer *timer = new QTimer (this); connect (timer, SIGNAL (timeout()), this, SLOT (update())); @@ -341,11 +338,13 @@ namespace CSVRender mLighting->deactivate(); mLighting = lighting; - mLighting->activate (mSceneManager, mHasDefaultAmbient ? &mDefaultAmbient : 0); + mLighting->activate (mSceneMgr, mHasDefaultAmbient ? &mDefaultAmbient : 0); } void SceneWidget::selectLightingMode (const std::string& mode) { + if (mode=="day") + setLighting (&mLightingDay); } } diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 5058fb860c..a1ecd733b9 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -5,6 +5,8 @@ #include +#include "lightingday.hpp" + namespace Ogre { class Camera; @@ -96,6 +98,7 @@ namespace CSVRender int mFastFactor; Ogre::ColourValue mDefaultAmbient; bool mHasDefaultAmbient; + LightingDay mLightingDay; private slots: From 9746f8bd32487c3de66bec834072c012454ca7ad Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 26 Mar 2014 17:59:42 +0100 Subject: [PATCH 104/127] added night lighting mode --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/view/render/lightingnight.cpp | 36 +++++++++++++++++++++++ apps/opencs/view/render/lightingnight.hpp | 31 +++++++++++++++++++ apps/opencs/view/render/scenewidget.cpp | 2 ++ apps/opencs/view/render/scenewidget.hpp | 2 ++ 5 files changed, 72 insertions(+), 1 deletion(-) create mode 100644 apps/opencs/view/render/lightingnight.cpp create mode 100644 apps/opencs/view/render/lightingnight.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 608f01d12c..a6200062da 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -69,7 +69,7 @@ opencs_units (view/render ) opencs_units_noqt (view/render - navigation navigation1st navigationfree navigationorbit lighting lightingday + navigation navigation1st navigationfree navigationorbit lighting lightingday lightingnight ) opencs_units_noqt (view/world diff --git a/apps/opencs/view/render/lightingnight.cpp b/apps/opencs/view/render/lightingnight.cpp new file mode 100644 index 0000000000..516bb3f408 --- /dev/null +++ b/apps/opencs/view/render/lightingnight.cpp @@ -0,0 +1,36 @@ + +#include "lightingnight.hpp" + +#include + +CSVRender::LightingNight::LightingNight() : mSceneManager (0), mLight (0) {} + +void CSVRender::LightingNight::activate (Ogre::SceneManager *sceneManager, + const Ogre::ColourValue *defaultAmbient) +{ + mSceneManager = sceneManager; + + if (defaultAmbient) + mSceneManager->setAmbientLight (*defaultAmbient); + else + mSceneManager->setAmbientLight (Ogre::ColourValue (0.2, 0.2, 0.2, 1)); + + mLight = mSceneManager->createLight(); + mLight->setType (Ogre::Light::LT_DIRECTIONAL); + mLight->setDirection (Ogre::Vector3 (0, 0, -1)); + mLight->setDiffuseColour (Ogre::ColourValue (0.2, 0.2, 0.2)); +} + +void CSVRender::LightingNight::deactivate() +{ + if (mLight) + { + mSceneManager->destroyLight (mLight); + mLight = 0; + } +} + +void CSVRender::LightingNight::setDefaultAmbient (const Ogre::ColourValue& colour) +{ + mSceneManager->setAmbientLight (colour); +} \ No newline at end of file diff --git a/apps/opencs/view/render/lightingnight.hpp b/apps/opencs/view/render/lightingnight.hpp new file mode 100644 index 0000000000..47d1d7ce82 --- /dev/null +++ b/apps/opencs/view/render/lightingnight.hpp @@ -0,0 +1,31 @@ +#ifndef OPENCS_VIEW_LIGHTING_NIGHT_H +#define OPENCS_VIEW_LIGHTING_NIGHT_H + +#include "lighting.hpp" + +namespace Ogre +{ + class Light; +} + +namespace CSVRender +{ + class LightingNight : public Lighting + { + Ogre::SceneManager *mSceneManager; + Ogre::Light *mLight; + + public: + + LightingNight(); + + virtual void activate (Ogre::SceneManager *sceneManager, + const Ogre::ColourValue *defaultAmbient = 0); + + virtual void deactivate(); + + virtual void setDefaultAmbient (const Ogre::ColourValue& colour); + }; +} + +#endif diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 77d9ea1e07..f1371041ca 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -345,6 +345,8 @@ namespace CSVRender { if (mode=="day") setLighting (&mLightingDay); + else if (mode=="night") + setLighting (&mLightingNight); } } diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index a1ecd733b9..96e7d7bb2c 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -6,6 +6,7 @@ #include #include "lightingday.hpp" +#include "lightingnight.hpp" namespace Ogre { @@ -99,6 +100,7 @@ namespace CSVRender Ogre::ColourValue mDefaultAmbient; bool mHasDefaultAmbient; LightingDay mLightingDay; + LightingNight mLightingNight; private slots: From ed524b2fd45e735ae8532ca7f07ded2a3c688882 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Wed, 26 Mar 2014 18:29:15 +0100 Subject: [PATCH 105/127] added bright lighting mode --- apps/opencs/CMakeLists.txt | 1 + apps/opencs/view/render/lightingbright.cpp | 30 +++++++++++++++++++++ apps/opencs/view/render/lightingbright.hpp | 31 ++++++++++++++++++++++ apps/opencs/view/render/scenewidget.cpp | 3 ++- apps/opencs/view/render/scenewidget.hpp | 2 ++ 5 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 apps/opencs/view/render/lightingbright.cpp create mode 100644 apps/opencs/view/render/lightingbright.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index a6200062da..a7a694463e 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -70,6 +70,7 @@ opencs_units (view/render opencs_units_noqt (view/render navigation navigation1st navigationfree navigationorbit lighting lightingday lightingnight + lightingbright ) opencs_units_noqt (view/world diff --git a/apps/opencs/view/render/lightingbright.cpp b/apps/opencs/view/render/lightingbright.cpp new file mode 100644 index 0000000000..ab845b924f --- /dev/null +++ b/apps/opencs/view/render/lightingbright.cpp @@ -0,0 +1,30 @@ + +#include "lightingbright.hpp" + +#include + +CSVRender::LightingBright::LightingBright() : mSceneManager (0), mLight (0) {} + +void CSVRender::LightingBright::activate (Ogre::SceneManager *sceneManager, + const Ogre::ColourValue *defaultAmbient) +{ + mSceneManager = sceneManager; + + mSceneManager->setAmbientLight (Ogre::ColourValue (1.0, 1.0, 1.0, 1)); + + mLight = mSceneManager->createLight(); + mLight->setType (Ogre::Light::LT_DIRECTIONAL); + mLight->setDirection (Ogre::Vector3 (0, 0, -1)); + mLight->setDiffuseColour (Ogre::ColourValue (1.0, 1.0, 1.0)); +} + +void CSVRender::LightingBright::deactivate() +{ + if (mLight) + { + mSceneManager->destroyLight (mLight); + mLight = 0; + } +} + +void CSVRender::LightingBright::setDefaultAmbient (const Ogre::ColourValue& colour) {} \ No newline at end of file diff --git a/apps/opencs/view/render/lightingbright.hpp b/apps/opencs/view/render/lightingbright.hpp new file mode 100644 index 0000000000..bc01899cb0 --- /dev/null +++ b/apps/opencs/view/render/lightingbright.hpp @@ -0,0 +1,31 @@ +#ifndef OPENCS_VIEW_LIGHTING_BRIGHT_H +#define OPENCS_VIEW_LIGHTING_BRIGHT_H + +#include "lighting.hpp" + +namespace Ogre +{ + class Light; +} + +namespace CSVRender +{ + class LightingBright : public Lighting + { + Ogre::SceneManager *mSceneManager; + Ogre::Light *mLight; + + public: + + LightingBright(); + + virtual void activate (Ogre::SceneManager *sceneManager, + const Ogre::ColourValue *defaultAmbient = 0); + + virtual void deactivate(); + + virtual void setDefaultAmbient (const Ogre::ColourValue& colour); + }; +} + +#endif diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index f1371041ca..1aee421ed7 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -347,6 +347,7 @@ namespace CSVRender setLighting (&mLightingDay); else if (mode=="night") setLighting (&mLightingNight); - + else if (mode=="bright") + setLighting (&mLightingBright); } } diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index 96e7d7bb2c..8df9cf3471 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -7,6 +7,7 @@ #include "lightingday.hpp" #include "lightingnight.hpp" +#include "lightingbright.hpp" namespace Ogre { @@ -101,6 +102,7 @@ namespace CSVRender bool mHasDefaultAmbient; LightingDay mLightingDay; LightingNight mLightingNight; + LightingBright mLightingBright; private slots: From 688415ce5476aeeb9bf91962f2294868e9d858e6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 26 Mar 2014 18:55:16 +0100 Subject: [PATCH 106/127] Play deathknockout/deathknockdown animations when appropriate --- apps/openmw/mwmechanics/character.cpp | 10 ++++++++++ apps/openmw/mwmechanics/character.hpp | 2 ++ 2 files changed, 12 insertions(+) diff --git a/apps/openmw/mwmechanics/character.cpp b/apps/openmw/mwmechanics/character.cpp index 2db3bacf0e..93c789af1a 100644 --- a/apps/openmw/mwmechanics/character.cpp +++ b/apps/openmw/mwmechanics/character.cpp @@ -414,6 +414,16 @@ void CharacterController::playRandomDeath(float startpoint) mDeathState = CharState_SwimDeath; mCurrentDeath = "swimdeath"; } + else if (mHitState == CharState_KnockDown) + { + mDeathState = CharState_DeathKnockDown; + mCurrentDeath = "deathknockdown"; + } + else if (mHitState == CharState_KnockOut) + { + mDeathState = CharState_DeathKnockOut; + mCurrentDeath = "deathknockout"; + } else { int selected=0; diff --git a/apps/openmw/mwmechanics/character.hpp b/apps/openmw/mwmechanics/character.hpp index 4009744efb..5aea0210f2 100644 --- a/apps/openmw/mwmechanics/character.hpp +++ b/apps/openmw/mwmechanics/character.hpp @@ -90,6 +90,8 @@ enum CharacterState { CharState_Death4, CharState_Death5, CharState_SwimDeath, + CharState_DeathKnockDown, + CharState_DeathKnockOut, CharState_Hit, CharState_KnockDown, From 793649c854d759a40fcb8b0421295a6f23c3ac2f Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 26 Mar 2014 19:55:52 +0100 Subject: [PATCH 107/127] ToggleAI: Report current status on toggle --- apps/openmw/mwbase/mechanicsmanager.hpp | 2 +- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 3 ++- apps/openmw/mwmechanics/mechanicsmanagerimp.hpp | 2 +- apps/openmw/mwscript/aiextensions.cpp | 7 ++++++- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwbase/mechanicsmanager.hpp b/apps/openmw/mwbase/mechanicsmanager.hpp index 22dda0ce09..e4c480a8c0 100644 --- a/apps/openmw/mwbase/mechanicsmanager.hpp +++ b/apps/openmw/mwbase/mechanicsmanager.hpp @@ -156,7 +156,7 @@ namespace MWBase /// paused we may want to do it manually (after equipping permanent enchantment) virtual void updateMagicEffects (const MWWorld::Ptr& ptr) = 0; - virtual void toggleAI() = 0; + virtual bool toggleAI() = 0; virtual bool isAIActive() = 0; virtual void getObjectsInRange (const Ogre::Vector3& position, float radius, std::vector& objects) = 0; diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 4c8f35edb0..3164ca1550 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -750,9 +750,10 @@ namespace MWMechanics mActors.updateMagicEffects(ptr); } - void MechanicsManager::toggleAI() + bool MechanicsManager::toggleAI() { mAI = !mAI; + return mAI; } bool MechanicsManager::isAIActive() diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp index 761caf586c..5dd7583779 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.hpp @@ -137,7 +137,7 @@ namespace MWMechanics virtual std::list getActorsFollowing(const MWWorld::Ptr& actor); - virtual void toggleAI(); + virtual bool toggleAI(); virtual bool isAIActive(); virtual void playerLoaded(); diff --git a/apps/openmw/mwscript/aiextensions.cpp b/apps/openmw/mwscript/aiextensions.cpp index 8314d011a9..a34c5476c9 100644 --- a/apps/openmw/mwscript/aiextensions.cpp +++ b/apps/openmw/mwscript/aiextensions.cpp @@ -464,7 +464,12 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { - MWBase::Environment::get().getMechanicsManager()->toggleAI(); + InterpreterContext& context + = static_cast (runtime.getContext()); + + bool enabled = MWBase::Environment::get().getMechanicsManager()->toggleAI(); + + context.report (enabled ? "AI -> On" : "AI -> Off"); } }; From 53ba23e3031e20ebd71d3af178cd9fcb95461702 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 26 Mar 2014 19:56:12 +0100 Subject: [PATCH 108/127] Fixes #1224: Store class name instead of id in savegame header --- apps/openmw/mwgui/savegamedialog.cpp | 2 +- apps/openmw/mwstate/statemanagerimp.cpp | 2 +- components/esm/savedgame.cpp | 4 ++-- components/esm/savedgame.hpp | 7 ++++++- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwgui/savegamedialog.cpp b/apps/openmw/mwgui/savegamedialog.cpp index 77ad98121b..894cbe0a3e 100644 --- a/apps/openmw/mwgui/savegamedialog.cpp +++ b/apps/openmw/mwgui/savegamedialog.cpp @@ -86,7 +86,7 @@ namespace MWGui { std::stringstream title; title << it->getSignature().mPlayerName; - title << " (Level " << it->getSignature().mPlayerLevel << " " << it->getSignature().mPlayerClass << ")"; + title << " (Level " << it->getSignature().mPlayerLevel << " " << it->getSignature().mPlayerClassName << ")"; mCharacterSelection->addItem (title.str()); diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index d6309c1c9f..a0d482f0a0 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -155,7 +155,7 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot profile.mPlayerName = player.getClass().getName (player); profile.mPlayerLevel = player.getClass().getNpcStats (player).getLevel(); - profile.mPlayerClass = player.get()->mBase->mClass; + profile.mPlayerClassName = world.getStore().get().find(player.get()->mBase->mClass)->mName; profile.mPlayerCell = world.getCellName(); diff --git a/components/esm/savedgame.cpp b/components/esm/savedgame.cpp index d6887f1704..813865e253 100644 --- a/components/esm/savedgame.cpp +++ b/components/esm/savedgame.cpp @@ -11,7 +11,7 @@ void ESM::SavedGame::load (ESMReader &esm) { mPlayerName = esm.getHNString("PLNA"); esm.getHNOT (mPlayerLevel, "PLLE"); - mPlayerClass = esm.getHNString("PLCL"); + mPlayerClassName = esm.getHNString("PLCL"); mPlayerCell = esm.getHNString("PLCE"); esm.getHNT (mInGameTime, "TSTM", 16); esm.getHNT (mTimePlayed, "TIME"); @@ -30,7 +30,7 @@ void ESM::SavedGame::save (ESMWriter &esm) const { esm.writeHNString ("PLNA", mPlayerName); esm.writeHNT ("PLLE", mPlayerLevel); - esm.writeHNString ("PLCL", mPlayerClass); + esm.writeHNString ("PLCL", mPlayerClassName); esm.writeHNString ("PLCE", mPlayerCell); esm.writeHNT ("TSTM", mInGameTime, 16); esm.writeHNT ("TIME", mTimePlayed); diff --git a/components/esm/savedgame.hpp b/components/esm/savedgame.hpp index 9c7bf551d7..b8615a6bc4 100644 --- a/components/esm/savedgame.hpp +++ b/components/esm/savedgame.hpp @@ -26,7 +26,12 @@ namespace ESM std::vector mContentFiles; std::string mPlayerName; int mPlayerLevel; - std::string mPlayerClass; // this is the ID and not the name of the class + // The (translated) name of the player class. So it will be displayed in the MW language + // the savegame was made in, not the currently running language of MW. + // However, savegames from a different MW language are not compatible anyway. + // And if only the ID was stored here, we would need to + // peek into the savegame to look for a class record in case it is a custom class. + std::string mPlayerClassName; std::string mPlayerCell; TimeStamp mInGameTime; double mTimePlayed; From ecfaa41e93699b0c20a717d76daf1f0e4ebf7661 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 26 Mar 2014 20:56:39 +0100 Subject: [PATCH 109/127] Savegame dialog: use locale-aware datetime format --- apps/openmw/mwgui/savegamedialog.cpp | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/savegamedialog.cpp b/apps/openmw/mwgui/savegamedialog.cpp index 894cbe0a3e..e897c5a6bc 100644 --- a/apps/openmw/mwgui/savegamedialog.cpp +++ b/apps/openmw/mwgui/savegamedialog.cpp @@ -241,7 +241,13 @@ namespace MWGui struct tm* timeinfo; timeinfo = localtime(&time); - text << asctime(timeinfo) << "\n"; + // Use system/environment locale settings for datetime formatting + std::setlocale(LC_TIME, ""); + + const int size=1024; + char buffer[size]; + if (std::strftime(buffer, size, "%x %X", timeinfo) > 0) + text << buffer << "\n"; text << "Level " << slot->mProfile.mPlayerLevel << "\n"; text << slot->mProfile.mPlayerCell << "\n"; // text << "Time played: " << slot->mProfile.mTimePlayed << "\n"; From 5562c78ac4933456b4e17e197b98b813bfa747e1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 26 Mar 2014 21:11:39 +0100 Subject: [PATCH 110/127] Ask for confirmation when selecting 'New Game' --- apps/openmw/mwgui/mainmenu.cpp | 17 ++++++++++++++++- apps/openmw/mwgui/mainmenu.hpp | 1 + 2 files changed, 17 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index 4ad260fd93..655663eb68 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -13,6 +13,7 @@ #include "../mwstate/character.hpp" #include "savegamedialog.hpp" +#include "confirmationdialog.hpp" namespace MWGui { @@ -62,6 +63,11 @@ namespace MWGui OEngine::GUI::Layout::setVisible (visible); } + void MainMenu::onNewGameConfirmed() + { + MWBase::Environment::get().getStateManager()->newGame(); + } + void MainMenu::onButtonClicked(MyGUI::Widget *sender) { std::string name = *sender->getUserData(); @@ -77,7 +83,16 @@ namespace MWGui MWBase::Environment::get().getStateManager()->requestQuit(); else if (name == "newgame") { - MWBase::Environment::get().getStateManager()->newGame(); + if (MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame) + onNewGameConfirmed(); + else + { + ConfirmationDialog* dialog = MWBase::Environment::get().getWindowManager()->getConfirmationDialog(); + dialog->open("#{sNotifyMessage54}"); + dialog->eventOkClicked.clear(); + dialog->eventOkClicked += MyGUI::newDelegate(this, &MainMenu::onNewGameConfirmed); + dialog->eventCancelClicked.clear(); + } } else diff --git a/apps/openmw/mwgui/mainmenu.hpp b/apps/openmw/mwgui/mainmenu.hpp index 722b329de1..f38b2b751b 100644 --- a/apps/openmw/mwgui/mainmenu.hpp +++ b/apps/openmw/mwgui/mainmenu.hpp @@ -32,6 +32,7 @@ namespace MWGui std::map mButtons; void onButtonClicked (MyGUI::Widget* sender); + void onNewGameConfirmed(); void updateMenu(); From 23f4bbc5b00c569ff542e86c13da827ce79b5b6c Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 26 Mar 2014 21:36:57 +0100 Subject: [PATCH 111/127] Videoplayer: only pause previous sounds if there is an audio stream --- apps/openmw/mwrender/videoplayer.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/videoplayer.cpp b/apps/openmw/mwrender/videoplayer.cpp index f3c0971e76..7abc8140a0 100644 --- a/apps/openmw/mwrender/videoplayer.cpp +++ b/apps/openmw/mwrender/videoplayer.cpp @@ -994,6 +994,9 @@ void VideoState::init(const std::string& resourceName) audio_index = i; } + if (audio_index != -1) + MWBase::Environment::get().getSoundManager()->pauseSounds(); + this->external_clock_base = av_gettime(); if(audio_index >= 0) this->stream_open(audio_index, this->format_ctx); @@ -1164,8 +1167,6 @@ void VideoPlayer::playVideo(const std::string &resourceName, bool allowSkipping) } mSceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE); - MWBase::Environment::get().getSoundManager()->pauseSounds(); - try { mState = new VideoState; mState->init(resourceName); From a5598e9c2e5e6f9b74a938ae45a9da87569fc628 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 26 Mar 2014 21:38:57 +0100 Subject: [PATCH 112/127] Add Credits button to main menu (plays mw_credits.bik) --- apps/openmw/mwgui/mainmenu.cpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index 655663eb68..4e4599e064 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -27,7 +27,7 @@ namespace MWGui std::stringstream sstream; sstream << "OpenMW version: " << OPENMW_VERSION; - // adding info about git hash if availible + // adding info about git hash if available std::string rev = OPENMW_VERSION_COMMITHASH; std::string tag = OPENMW_VERSION_TAGHASH; if (!rev.empty() && !tag.empty()) @@ -79,6 +79,8 @@ namespace MWGui } else if (name == "options") MWBase::Environment::get().getWindowManager ()->pushGuiMode (GM_Settings); + else if (name == "credits") + MWBase::Environment::get().getWorld()->playVideo("mw_credits.bik", true); else if (name == "exitgame") MWBase::Environment::get().getStateManager()->requestQuit(); else if (name == "newgame") @@ -135,7 +137,10 @@ namespace MWGui buttons.push_back("savegame"); buttons.push_back("options"); - //buttons.push_back("credits"); + + if (state==MWBase::StateManager::State_NoGame) + buttons.push_back("credits"); + buttons.push_back("exitgame"); // Create new buttons if needed From e5e1e84c5270f9120a39e7b7d676ba8c7298a516 Mon Sep 17 00:00:00 2001 From: scrawl Date: Wed, 26 Mar 2014 22:05:21 +0100 Subject: [PATCH 113/127] Ask for confirmation to exit OpenMW --- apps/openmw/mwgui/mainmenu.cpp | 18 +++++++++++++++++- apps/openmw/mwgui/mainmenu.hpp | 1 + 2 files changed, 18 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index 4e4599e064..25821663df 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -68,6 +68,11 @@ namespace MWGui MWBase::Environment::get().getStateManager()->newGame(); } + void MainMenu::onExitConfirmed() + { + MWBase::Environment::get().getStateManager()->requestQuit(); + } + void MainMenu::onButtonClicked(MyGUI::Widget *sender) { std::string name = *sender->getUserData(); @@ -82,7 +87,18 @@ namespace MWGui else if (name == "credits") MWBase::Environment::get().getWorld()->playVideo("mw_credits.bik", true); else if (name == "exitgame") - MWBase::Environment::get().getStateManager()->requestQuit(); + { + if (MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame) + onExitConfirmed(); + else + { + ConfirmationDialog* dialog = MWBase::Environment::get().getWindowManager()->getConfirmationDialog(); + dialog->open("#{sMessage2}"); + dialog->eventOkClicked.clear(); + dialog->eventOkClicked += MyGUI::newDelegate(this, &MainMenu::onExitConfirmed); + dialog->eventCancelClicked.clear(); + } + } else if (name == "newgame") { if (MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame) diff --git a/apps/openmw/mwgui/mainmenu.hpp b/apps/openmw/mwgui/mainmenu.hpp index f38b2b751b..1850c473c3 100644 --- a/apps/openmw/mwgui/mainmenu.hpp +++ b/apps/openmw/mwgui/mainmenu.hpp @@ -33,6 +33,7 @@ namespace MWGui void onButtonClicked (MyGUI::Widget* sender); void onNewGameConfirmed(); + void onExitConfirmed(); void updateMenu(); From 0e78ffe8c0b317e38e358d0b57504403ab5acf8b Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 27 Mar 2014 00:10:46 +0100 Subject: [PATCH 114/127] Add option to disable SDL's "minimize on focus loss" in fullscreen --- files/settings-default.cfg | 3 +++ 1 file changed, 3 insertions(+) diff --git a/files/settings-default.cfg b/files/settings-default.cfg index 5dfc054553..6361476e34 100644 --- a/files/settings-default.cfg +++ b/files/settings-default.cfg @@ -8,6 +8,9 @@ resolution y = 600 fullscreen = false screen = 0 +# Minimize the window if it loses key focus? +minimize on focus loss = true + # Render system # blank means default # Valid values: From 27956f362431127d92f2bafc7008c55d37241db6 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 27 Mar 2014 02:36:21 +0100 Subject: [PATCH 115/127] Savegame dialog: Hide main menu after successful load --- apps/openmw/mwgui/savegamedialog.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/apps/openmw/mwgui/savegamedialog.cpp b/apps/openmw/mwgui/savegamedialog.cpp index e897c5a6bc..6971358c17 100644 --- a/apps/openmw/mwgui/savegamedialog.cpp +++ b/apps/openmw/mwgui/savegamedialog.cpp @@ -169,7 +169,10 @@ namespace MWGui else { if (mCurrentCharacter && slot) + { MWBase::Environment::get().getStateManager()->loadGame (mCurrentCharacter, slot); + MWBase::Environment::get().getWindowManager()->removeGuiMode (MWGui::GM_MainMenu); + } } setVisible(false); From bcacdc49afc039c4fcbdbc9d12cb2cfb508e682d Mon Sep 17 00:00:00 2001 From: Rohit Nirmal Date: Wed, 26 Mar 2014 21:08:31 -0500 Subject: [PATCH 116/127] Update weapon icon in HUD when save is loaded. --- apps/openmw/mwstate/statemanagerimp.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index c0860b7849..c807c5e235 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -25,6 +25,7 @@ #include "../mwworld/player.hpp" #include "../mwworld/class.hpp" #include "../mwworld/cellstore.hpp" +#include "../mwworld/inventorystore.hpp" #include "../mwmechanics/npcstats.hpp" @@ -303,6 +304,10 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl MWBase::Environment::get().getMechanicsManager()->playerLoaded(); MWWorld::Ptr ptr = MWBase::Environment::get().getWorld()->getPlayerPtr(); + + //Update the weapon icon in the hud with whatever the player is currently holding. + MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr); + MWBase::Environment::get().getWindowManager()->setSelectedWeapon(*invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight)); ESM::CellId cellId = ptr.getCell()->getCell()->getCellId(); From e695890e014e0d2778e7c16720ed70ed11f354f9 Mon Sep 17 00:00:00 2001 From: Rohit Nirmal Date: Wed, 26 Mar 2014 21:53:35 -0500 Subject: [PATCH 117/127] Only update the icon if player is NOT unarmed, to avoid bad dereference. --- apps/openmw/mwstate/statemanagerimp.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index c807c5e235..5430caae56 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -307,7 +307,10 @@ void MWState::StateManager::loadGame (const Character *character, const Slot *sl //Update the weapon icon in the hud with whatever the player is currently holding. MWWorld::InventoryStore& invStore = ptr.getClass().getInventoryStore(ptr); - MWBase::Environment::get().getWindowManager()->setSelectedWeapon(*invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight)); + MWWorld::ContainerStoreIterator item = invStore.getSlot(MWWorld::InventoryStore::Slot_CarriedRight); + + if (item != invStore.end()) + MWBase::Environment::get().getWindowManager()->setSelectedWeapon(*item); ESM::CellId cellId = ptr.getCell()->getCell()->getCellId(); From 2a8bf46607429dfa788338689cb92d06f6ad6904 Mon Sep 17 00:00:00 2001 From: Jeffrey Haines Date: Thu, 27 Mar 2014 01:23:56 -0400 Subject: [PATCH 118/127] Trader Gold Reset Delay Implemented traded gold reset delay. Note: Traders gold pool is still in inventory. --- apps/openmw/mwclass/creature.cpp | 7 ++++- apps/openmw/mwclass/npc.cpp | 7 +++++ apps/openmw/mwgui/tradewindow.cpp | 35 +++++++++++++++++++++++ apps/openmw/mwgui/tradewindow.hpp | 4 +++ apps/openmw/mwmechanics/creaturestats.cpp | 20 +++++++++++++ apps/openmw/mwmechanics/creaturestats.hpp | 12 ++++++++ 6 files changed, 84 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index 0f7ffdc480..a224de71ef 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -123,6 +123,11 @@ namespace MWClass else data->mContainerStore = new MWWorld::ContainerStore(); + // Relates to NPC gold reset delay + data->mCreatureStats.setTradeTime (MWBase::Environment::get().getWorld()->getTimeStamp()); + + data->mCreatureStats.setGoldPool(ref->mBase->mData.mGold); + // store ptr.getRefData().setCustomData (data.release()); @@ -134,7 +139,7 @@ namespace MWClass getContainerStore(ptr).add(MWWorld::ContainerStore::sGoldId, ref->mBase->mData.mGold, ptr); if (ref->mBase->mFlags & ESM::Creature::Weapon) - getInventoryStore(ptr).autoEquip(ptr); + getInventoryStore(ptr).autoEquip(ptr); } } diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 3fbd0d5b21..502ff6ef6c 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -357,6 +357,11 @@ namespace MWClass data->mInventoryStore.fill(ref->mBase->mInventory, getId(ptr), "", MWBase::Environment::get().getWorld()->getStore()); + // Relates to NPC gold reset delay + data->mNpcStats.setTradeTime(MWBase::Environment::get().getWorld()->getTimeStamp()); + + data->mNpcStats.setGoldPool(gold); + // store ptr.getRefData().setCustomData (data.release()); @@ -365,6 +370,8 @@ namespace MWClass getContainerStore(ptr).add(MWWorld::ContainerStore::sGoldId, gold, ptr); getInventoryStore(ptr).autoEquip(ptr); + + } } diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 92ba9470d4..41c3cd197a 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -84,8 +84,11 @@ namespace MWGui mCurrentBalance = 0; mCurrentMerchantOffer = 0; + checkTradeTime(); + std::vector itemSources; MWBase::Environment::get().getWorld()->getContainersOwnedBy(actor, itemSources); + // Important: actor goes last, so that items purchased by the merchant go into his inventory itemSources.push_back(actor); std::vector worldItems; @@ -360,6 +363,8 @@ namespace MWGui addOrRemoveGold(-mCurrentBalance, mPtr); } + updateTradeTime(); + MWBase::Environment::get().getWindowManager()->getDialogueWindow()->addResponse( MWBase::Environment::get().getWorld()->getStore().get().find("sBarterDialog5")->getString()); @@ -474,4 +479,34 @@ namespace MWGui } return merchantGold; } + + // Relates to NPC gold reset delay + void TradeWindow::checkTradeTime() + { + MWWorld::ContainerStore store = mPtr.getClass().getContainerStore(mPtr); + MWWorld::LiveCellRef *ref = mPtr.get(); + const MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr); + double delay = boost::lexical_cast(MWBase::Environment::get().getWorld()->getStore().get().find("fBarterGoldResetDelay")->getInt()); + + // if time stamp longer than gold reset delay, reset gold. + if (MWBase::Environment::get().getWorld()->getTimeStamp() >= sellerStats.getTradeTime() + delay) + { + addOrRemoveGold(-store.count(MWWorld::ContainerStore::sGoldId), mPtr); + addOrRemoveGold(+ref->mBase->mNpdt52.mGold, mPtr); + } + } + + void TradeWindow::updateTradeTime() + { + MWWorld::ContainerStore store = mPtr.getClass().getContainerStore(mPtr); + MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr); + double delay = boost::lexical_cast(MWBase::Environment::get().getWorld()->getStore().get().find("fBarterGoldResetDelay")->getInt()); + + // If trade timestamp is within reset delay don't set + if ( ! (MWBase::Environment::get().getWorld()->getTimeStamp() >= sellerStats.getTradeTime() && + MWBase::Environment::get().getWorld()->getTimeStamp() < sellerStats.getTradeTime() + delay) ) + { + sellerStats.setTradeTime(MWBase::Environment::get().getWorld()->getTimeStamp()); + } + } } diff --git a/apps/openmw/mwgui/tradewindow.hpp b/apps/openmw/mwgui/tradewindow.hpp index 1a8999e6e5..5c154d4259 100644 --- a/apps/openmw/mwgui/tradewindow.hpp +++ b/apps/openmw/mwgui/tradewindow.hpp @@ -100,6 +100,10 @@ namespace MWGui virtual void onReferenceUnavailable(); int getMerchantGold(); + + // Relates to NPC gold reset delay + void checkTradeTime(); + void updateTradeTime(); }; } diff --git a/apps/openmw/mwmechanics/creaturestats.cpp b/apps/openmw/mwmechanics/creaturestats.cpp index d61b967390..feed8d182b 100644 --- a/apps/openmw/mwmechanics/creaturestats.cpp +++ b/apps/openmw/mwmechanics/creaturestats.cpp @@ -476,4 +476,24 @@ namespace MWMechanics for (int i=0; i<3; ++i) mDynamic[i].readState (state.mDynamic[i]); } + + // Relates to NPC gold reset delay + void CreatureStats::setTradeTime(MWWorld::TimeStamp tradeTime) + { + mTradeTime = tradeTime; + } + + MWWorld::TimeStamp CreatureStats::getTradeTime() const + { + return mTradeTime; + } + + void CreatureStats::setGoldPool(int pool) + { + mGoldPool = pool; + } + int CreatureStats::getGoldPool() const + { + return mGoldPool; + } } diff --git a/apps/openmw/mwmechanics/creaturestats.hpp b/apps/openmw/mwmechanics/creaturestats.hpp index 94e506fc4f..20a9a5799e 100644 --- a/apps/openmw/mwmechanics/creaturestats.hpp +++ b/apps/openmw/mwmechanics/creaturestats.hpp @@ -54,6 +54,11 @@ namespace MWMechanics bool mRecalcDynamicStats; std::map mUsedPowers; + + MWWorld::TimeStamp mTradeTime; // Relates to NPC gold reset delay + + int mGoldPool; // the pool of merchant gold not in inventory + protected: bool mIsWerewolf; AttributeValue mWerewolfAttributes[8]; @@ -221,6 +226,13 @@ namespace MWMechanics void writeState (ESM::CreatureStats& state) const; void readState (const ESM::CreatureStats& state); + + // Relates to NPC gold reset delay + void setTradeTime(MWWorld::TimeStamp tradeTime); + MWWorld::TimeStamp getTradeTime() const; + + void setGoldPool(int pool); + int getGoldPool() const; }; } From 53c4878d5257d139c63e5ae72b4fecdeb17aa8f7 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 27 Mar 2014 10:01:42 +0100 Subject: [PATCH 119/127] fix for inconsistent case in topic records --- apps/opencs/model/world/collection.hpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/collection.hpp b/apps/opencs/model/world/collection.hpp index 9d97e36c76..1fb3e1f1db 100644 --- a/apps/opencs/model/world/collection.hpp +++ b/apps/opencs/model/world/collection.hpp @@ -448,7 +448,8 @@ namespace CSMWorld template void Collection::setRecord (int index, const Record& record) { - if (IdAccessorT().getId (mRecords.at (index).get())!=IdAccessorT().getId (record.get())) + if (Misc::StringUtils::lowerCase (IdAccessorT().getId (mRecords.at (index).get()))!= + Misc::StringUtils::lowerCase (IdAccessorT().getId (record.get()))) throw std::runtime_error ("attempt to change the ID of a record"); mRecords.at (index) = record; From 6896142db17a53f5df20a156df8ac136c67b6b59 Mon Sep 17 00:00:00 2001 From: Jeffrey Haines Date: Thu, 27 Mar 2014 07:30:24 -0400 Subject: [PATCH 120/127] Trader Gold Reset Delay MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Trade Time initialized to 0 Gold pot set correctly for npc’s and creatures --- apps/openmw/mwclass/creature.cpp | 4 ++-- apps/openmw/mwclass/npc.cpp | 2 +- apps/openmw/mwgui/tradewindow.cpp | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwclass/creature.cpp b/apps/openmw/mwclass/creature.cpp index a224de71ef..72b3154845 100644 --- a/apps/openmw/mwclass/creature.cpp +++ b/apps/openmw/mwclass/creature.cpp @@ -124,12 +124,12 @@ namespace MWClass data->mContainerStore = new MWWorld::ContainerStore(); // Relates to NPC gold reset delay - data->mCreatureStats.setTradeTime (MWBase::Environment::get().getWorld()->getTimeStamp()); + data->mCreatureStats.setTradeTime(MWWorld::TimeStamp(0.0, 0)); data->mCreatureStats.setGoldPool(ref->mBase->mData.mGold); // store - ptr.getRefData().setCustomData (data.release()); + ptr.getRefData().setCustomData(data.release()); getContainerStore(ptr).fill(ref->mBase->mInventory, getId(ptr), "", MWBase::Environment::get().getWorld()->getStore()); diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index 502ff6ef6c..020f3b3af2 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -358,7 +358,7 @@ namespace MWClass MWBase::Environment::get().getWorld()->getStore()); // Relates to NPC gold reset delay - data->mNpcStats.setTradeTime(MWBase::Environment::get().getWorld()->getTimeStamp()); + data->mNpcStats.setTradeTime(MWWorld::TimeStamp(0.0, 0)); data->mNpcStats.setGoldPool(gold); diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index 41c3cd197a..0525a97aee 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -484,7 +484,6 @@ namespace MWGui void TradeWindow::checkTradeTime() { MWWorld::ContainerStore store = mPtr.getClass().getContainerStore(mPtr); - MWWorld::LiveCellRef *ref = mPtr.get(); const MWMechanics::CreatureStats &sellerStats = mPtr.getClass().getCreatureStats(mPtr); double delay = boost::lexical_cast(MWBase::Environment::get().getWorld()->getStore().get().find("fBarterGoldResetDelay")->getInt()); @@ -492,7 +491,7 @@ namespace MWGui if (MWBase::Environment::get().getWorld()->getTimeStamp() >= sellerStats.getTradeTime() + delay) { addOrRemoveGold(-store.count(MWWorld::ContainerStore::sGoldId), mPtr); - addOrRemoveGold(+ref->mBase->mNpdt52.mGold, mPtr); + addOrRemoveGold(+sellerStats.getGoldPool(), mPtr); } } From 2e4ef93b28630f6f2ec8ccbe7eb2627e3912d6d1 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 27 Mar 2014 04:15:47 +0100 Subject: [PATCH 121/127] Add proper main menu (background image, logo animation, title music) --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/engine.cpp | 31 +++++++++++++++-- apps/openmw/mwgui/mainmenu.cpp | 61 +++++++++++++++++++++++++++++++--- apps/openmw/mwgui/mainmenu.hpp | 4 +++ files/mygui/openmw_layers.xml | 2 +- 5 files changed, 91 insertions(+), 9 deletions(-) diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 20011b0d99..19f3473f79 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -33,7 +33,7 @@ add_openmw_dir (mwgui merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview tradeitemmodel companionitemmodel pickpocketitemmodel fontloader controllers savegamedialog - recharge + recharge mode ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 47e0d016f5..a710ce59a7 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -339,6 +339,9 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) std::string aa = settings.getString("antialiasing", "Video"); windowSettings.fsaa = (aa.substr(0, 4) == "MSAA") ? aa.substr(5, aa.size()-5) : "0"; + SDL_SetHint(SDL_HINT_VIDEO_MINIMIZE_ON_FOCUS_LOSS, + settings.getBool("minimize on focus loss", "Video") ? "1" : "0"); + mOgre->createWindow("OpenMW", windowSettings); Bsa::registerResources (mFileCollections, mArchives, true, mFSStrict); @@ -356,6 +359,18 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) mCfgMgr.getCachePath ().string(), mScriptConsoleMode, mTranslationDataStorage, mEncoding); mEnvironment.setWindowManager (window); + // Create sound system + mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound)); + + // TODO: play pre-load intro videos. Need to find a way to have them receive input. + // Make videoplayer a MyGUI widget? + /* + { + MWRender::VideoPlayer player(mOgre->getScene(), mOgre->getWindow()); + player.playVideo("mw_logo.bik", 1); + } + */ + // Create the world mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mContentFiles, mResDir, mCfgMgr.getCachePath(), mEncoder, mFallbackMap, @@ -373,9 +388,6 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) Compiler::registerExtensions (mExtensions); - // Create sound system - mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound)); - // Create script system mScriptContext = new MWScript::CompilerContext (MWScript::CompilerContext::Type_Full); mScriptContext->setExtensions (&mExtensions); @@ -434,7 +446,20 @@ void OMW::Engine::go() // start in main menu if (!mSkipMenu) + { MWBase::Environment::get().getWindowManager()->pushGuiMode (MWGui::GM_MainMenu); + try + { + // Is there an ini setting for this filename or something? + MWBase::Environment::get().getSoundManager()->streamMusic("Special/morrowind title.mp3"); + + // TODO: there are other intro videos, too. They need to be imported from Morrowind.ini. + // Unfortunately those must play BEFORE any loading is done, which will currently not work. + // The videoplayer is created by World, so all content files must be loaded first... + MWBase::Environment::get().getWorld()->playVideo("mw_logo.bik", true); + } + catch (...) {} + } else MWBase::Environment::get().getStateManager()->newGame (true); diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index 25821663df..0bc8b07d1d 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -22,6 +22,7 @@ namespace MWGui : OEngine::GUI::Layout("openmw_mainmenu.layout") , mButtonBox(0), mWidth (w), mHeight (h) , mSaveGameDialog(NULL) + , mBackground(NULL) { getWidget(mVersionText, "VersionText"); std::stringstream sstream; @@ -59,6 +60,10 @@ namespace MWGui { if (visible) updateMenu(); + else + showBackground( + MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu) && + MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame); OEngine::GUI::Layout::setVisible (visible); } @@ -125,11 +130,42 @@ namespace MWGui } } + void MainMenu::showBackground(bool show) + { + if (mBackground) + { + MyGUI::Gui::getInstance().destroyWidget(mBackground); + mBackground = NULL; + } + if (show) + { + if (!mBackground) + { + mBackground = MyGUI::Gui::getInstance().createWidgetReal("ImageBox", 0,0,1,1, + MyGUI::Align::Stretch, "Menu"); + mBackground->setImageTexture("black.png"); + + // Use black bars to correct aspect ratio. The video player also does it, so we need to do it + // for mw_logo.bik to align correctly with menu_morrowind.dds. + MyGUI::IntSize screenSize = MyGUI::RenderManager::getInstance().getViewSize(); + + // No way to un-hardcode this right now, menu_morrowind.dds is 1024x512 but was designed for 4:3 + double imageaspect = 4.0/3.0; + + int leftPadding = std::max(0.0, (screenSize.width - screenSize.height * imageaspect) / 2); + int topPadding = std::max(0.0, (screenSize.height - screenSize.width / imageaspect) / 2); + + MyGUI::ImageBox* image = mBackground->createWidget("ImageBox", + leftPadding, topPadding, screenSize.width - leftPadding*2, screenSize.height - topPadding*2, MyGUI::Align::Default); + image->setImageTexture("textures\\menu_morrowind.dds"); + } + } + } + void MainMenu::updateMenu() { setCoord(0,0, mWidth, mHeight); - if (!mButtonBox) mButtonBox = mMainWidget->createWidget("", MyGUI::IntCoord(0, 0, 0, 0), MyGUI::Align::Default); @@ -137,6 +173,8 @@ namespace MWGui MWBase::StateManager::State state = MWBase::Environment::get().getStateManager()->getState(); + showBackground(state == MWBase::StateManager::State_NoGame); + std::vector buttons; if (state==MWBase::StateManager::State_Running) @@ -191,12 +229,27 @@ namespace MWGui assert(mButtons.find(*it) != mButtons.end()); MWGui::ImageButton* button = mButtons[*it]; button->setVisible(true); + MyGUI::IntSize requested = button->getRequestedSize(); - button->setCoord((maxwidth-requested.width) / 2, curH, requested.width, requested.height); - curH += requested.height; + + // Trim off some of the excessive padding + // TODO: perhaps do this within ImageButton? + int trim = 8; + button->setImageCoord(MyGUI::IntCoord(0, trim, requested.width, requested.height-trim)); + int height = requested.height-trim*2; + button->setImageTile(MyGUI::IntSize(requested.width, height)); + button->setCoord((maxwidth-requested.width) / 2, curH, requested.width, height); + curH += height; } - mButtonBox->setCoord (mWidth/2 - maxwidth/2, mHeight/2 - curH/2, maxwidth, curH); + if (state == MWBase::StateManager::State_NoGame) + { + // Align with the background image + int bottomPadding=48; + mButtonBox->setCoord (mWidth/2 - maxwidth/2, mHeight - curH - bottomPadding, maxwidth, curH); + } + else + mButtonBox->setCoord (mWidth/2 - maxwidth/2, mHeight/2 - curH/2, maxwidth, curH); } } diff --git a/apps/openmw/mwgui/mainmenu.hpp b/apps/openmw/mwgui/mainmenu.hpp index 1850c473c3..c571fda861 100644 --- a/apps/openmw/mwgui/mainmenu.hpp +++ b/apps/openmw/mwgui/mainmenu.hpp @@ -29,12 +29,16 @@ namespace MWGui MyGUI::Widget* mButtonBox; MyGUI::TextBox* mVersionText; + MyGUI::ImageBox* mBackground; + std::map mButtons; void onButtonClicked (MyGUI::Widget* sender); void onNewGameConfirmed(); void onExitConfirmed(); + void showBackground(bool show); + void updateMenu(); SaveGameDialog* mSaveGameDialog; diff --git a/files/mygui/openmw_layers.xml b/files/mygui/openmw_layers.xml index 84ec6f7c50..8bd95e2cd3 100644 --- a/files/mygui/openmw_layers.xml +++ b/files/mygui/openmw_layers.xml @@ -1,8 +1,8 @@ - + From 7026a0ceee3fe0a667bd21863e5c69c2af4244dd Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 27 Mar 2014 15:46:49 +0100 Subject: [PATCH 122/127] updated credits file --- credits.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/credits.txt b/credits.txt index 7d2a5ca42f..cd533de3a2 100644 --- a/credits.txt +++ b/credits.txt @@ -37,6 +37,7 @@ gugus/gus Jacob Essex (Yacoby) Jannik Heller (scrawl) Jason Hooks (jhooks) +Jeffrey Haines (Jyby) Joel Graff (graffy) John Blomberg (fstp) Jordan Milne From 5906d795c0dc936a17e51a3fe37b12faada56160 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 27 Mar 2014 19:10:15 +0100 Subject: [PATCH 123/127] Refactored video player (now a MyGUI widget) --- apps/openmw/CMakeLists.txt | 2 +- apps/openmw/engine.cpp | 2 +- apps/openmw/mwbase/windowmanager.hpp | 4 + apps/openmw/mwbase/world.hpp | 2 - apps/openmw/mwgui/mainmenu.cpp | 2 +- apps/openmw/mwgui/mode.hpp | 4 +- apps/openmw/mwgui/videowidget.cpp | 45 ++++++ apps/openmw/mwgui/videowidget.hpp | 39 +++++ apps/openmw/mwgui/windowmanagerimp.cpp | 71 +++++++- apps/openmw/mwgui/windowmanagerimp.hpp | 10 ++ apps/openmw/mwinput/inputmanagerimp.cpp | 4 +- apps/openmw/mwrender/renderingmanager.cpp | 19 --- apps/openmw/mwrender/renderingmanager.hpp | 5 - apps/openmw/mwrender/videoplayer.cpp | 188 +++++++--------------- apps/openmw/mwrender/videoplayer.hpp | 31 ++-- apps/openmw/mwscript/miscextensions.cpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 12 +- apps/openmw/mwworld/worldimp.hpp | 2 - files/mygui/openmw_layers.xml | 1 + 19 files changed, 242 insertions(+), 203 deletions(-) create mode 100644 apps/openmw/mwgui/videowidget.cpp create mode 100644 apps/openmw/mwgui/videowidget.hpp diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 19f3473f79..511435108e 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -33,7 +33,7 @@ add_openmw_dir (mwgui merchantrepair repair soulgemdialog companionwindow bookpage journalviewmodel journalbooks keywordsearch itemmodel containeritemmodel inventoryitemmodel sortfilteritemmodel itemview tradeitemmodel companionitemmodel pickpocketitemmodel fontloader controllers savegamedialog - recharge mode + recharge mode videowidget ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index a710ce59a7..a118152edd 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -456,7 +456,7 @@ void OMW::Engine::go() // TODO: there are other intro videos, too. They need to be imported from Morrowind.ini. // Unfortunately those must play BEFORE any loading is done, which will currently not work. // The videoplayer is created by World, so all content files must be loaded first... - MWBase::Environment::get().getWorld()->playVideo("mw_logo.bik", true); + MWBase::Environment::get().getWindowManager()->playVideo("mw_logo.bik", true); } catch (...) {} } diff --git a/apps/openmw/mwbase/windowmanager.hpp b/apps/openmw/mwbase/windowmanager.hpp index 4fce19e337..e3bd428e22 100644 --- a/apps/openmw/mwbase/windowmanager.hpp +++ b/apps/openmw/mwbase/windowmanager.hpp @@ -96,6 +96,10 @@ namespace MWBase */ virtual void update() = 0; + /// @note This method will block until the video finishes playing + /// (and will continually update the window while doing so) + virtual void playVideo(const std::string& name, bool allowSkipping) = 0; + virtual void setNewGame(bool newgame) = 0; virtual void pushGuiMode (MWGui::GuiMode mode) = 0; diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index bb6f5741d9..f03a9197d9 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -420,8 +420,6 @@ namespace MWBase virtual MWRender::Animation* getAnimation(const MWWorld::Ptr &ptr) = 0; /// \todo this does not belong here - virtual void playVideo(const std::string& name, bool allowSkipping) = 0; - virtual void stopVideo() = 0; virtual void frameStarted (float dt, bool paused) = 0; virtual void screenshot (Ogre::Image& image, int w, int h) = 0; diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp index 0bc8b07d1d..00e124f6c2 100644 --- a/apps/openmw/mwgui/mainmenu.cpp +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -90,7 +90,7 @@ namespace MWGui else if (name == "options") MWBase::Environment::get().getWindowManager ()->pushGuiMode (GM_Settings); else if (name == "credits") - MWBase::Environment::get().getWorld()->playVideo("mw_credits.bik", true); + MWBase::Environment::get().getWindowManager()->playVideo("mw_credits.bik", true); else if (name == "exitgame") { if (MWBase::Environment::get().getStateManager()->getState() == MWBase::StateManager::State_NoGame) diff --git a/apps/openmw/mwgui/mode.hpp b/apps/openmw/mwgui/mode.hpp index 50d53abacd..a1688d2e53 100644 --- a/apps/openmw/mwgui/mode.hpp +++ b/apps/openmw/mwgui/mode.hpp @@ -47,9 +47,7 @@ namespace MWGui GM_Loading, GM_LoadingWallpaper, - GM_QuickKeysMenu, - - GM_Video + GM_QuickKeysMenu }; // Windows shown in inventory mode diff --git a/apps/openmw/mwgui/videowidget.cpp b/apps/openmw/mwgui/videowidget.cpp new file mode 100644 index 0000000000..566c7cadbb --- /dev/null +++ b/apps/openmw/mwgui/videowidget.cpp @@ -0,0 +1,45 @@ +#include "videowidget.hpp" + +namespace MWGui +{ + +VideoWidget::VideoWidget() + : mAllowSkipping(true) +{ + eventKeyButtonPressed += MyGUI::newDelegate(this, &VideoWidget::onKeyPressed); + + setNeedKeyFocus(true); +} + +void VideoWidget::playVideo(const std::string &video, bool allowSkipping) +{ + mAllowSkipping = allowSkipping; + + mPlayer.playVideo(video); + + setImageTexture(mPlayer.getTextureName()); +} + +int VideoWidget::getVideoWidth() +{ + return mPlayer.getVideoWidth(); +} + +int VideoWidget::getVideoHeight() +{ + return mPlayer.getVideoHeight(); +} + +void VideoWidget::onKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char) +{ + if (_key == MyGUI::KeyCode::Escape && mAllowSkipping) + mPlayer.stopVideo(); +} + +bool VideoWidget::update() +{ + mPlayer.update(); + return mPlayer.isPlaying(); +} + +} diff --git a/apps/openmw/mwgui/videowidget.hpp b/apps/openmw/mwgui/videowidget.hpp new file mode 100644 index 0000000000..16a71d367d --- /dev/null +++ b/apps/openmw/mwgui/videowidget.hpp @@ -0,0 +1,39 @@ +#ifndef OPENMW_MWGUI_VIDEOWIDGET_H +#define OPENMW_MWGUI_VIDEOWIDGET_H + +#include + +#include "../mwrender/videoplayer.hpp" + +namespace MWGui +{ + + /** + * Widget that plays a video. Can be skipped by pressing Esc. + */ + class VideoWidget : public MyGUI::ImageBox + { + public: + MYGUI_RTTI_DERIVED(VideoWidget) + + VideoWidget(); + + void playVideo (const std::string& video, bool allowSkipping); + + int getVideoWidth(); + int getVideoHeight(); + + /// @return Is the video still playing? + bool update(); + + private: + bool mAllowSkipping; + + MWRender::VideoPlayer mPlayer; + + void onKeyPressed(MyGUI::Widget *_sender, MyGUI::KeyCode _key, MyGUI::Char _char); + }; + +} + +#endif diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index 1b71157a74..ca8459fa1e 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -4,6 +4,7 @@ #include #include +#include #include "MyGUI_UString.h" #include "MyGUI_IPointer.h" @@ -59,6 +60,7 @@ #include "bookpage.hpp" #include "itemview.hpp" #include "fontloader.hpp" +#include "videowidget.hpp" namespace MWGui { @@ -104,6 +106,8 @@ namespace MWGui , mRecharge(NULL) , mRepair(NULL) , mCompanionWindow(NULL) + , mVideoBackground(NULL) + , mVideoWidget(NULL) , mTranslationDataStorage (translationDataStorage) , mCharGen(NULL) , mInputBlocker(NULL) @@ -155,6 +159,7 @@ namespace MWGui MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); MyGUI::FactoryManager::getInstance().registerFactory("Widget"); + MyGUI::FactoryManager::getInstance().registerFactory("Widget"); BookPage::registerMyGUIComponents (); ItemView::registerComponents(); @@ -186,6 +191,13 @@ namespace MWGui // hide mygui's pointer MyGUI::PointerManager::getInstance().setVisible(false); + + mVideoBackground = MyGUI::Gui::getInstance().createWidgetReal("ImageBox", 0,0,1,1, + MyGUI::Align::Default, "Overlay"); + mVideoBackground->setImageTexture("black.png"); + mVideoBackground->setVisible(false); + + mVideoWidget = mVideoBackground->createWidgetReal("ImageBox", 0,0,1,1, MyGUI::Align::Default); } void WindowManager::initUI() @@ -391,6 +403,7 @@ namespace MWGui mCompanionWindow->setVisible(false); mInventoryWindow->setTrading(false); mRecharge->setVisible(false); + mVideoBackground->setVisible(false); mHud->setVisible(mHudEnabled); @@ -539,10 +552,6 @@ namespace MWGui setCursorVisible(false); break; - case GM_Video: - setCursorVisible(false); - mHud->setVisible(false); - break; default: // Unsupported mode, switch back to game break; @@ -894,6 +903,7 @@ namespace MWGui void WindowManager::windowResized(int x, int y) { + sizeVideo(x, y); mGuiManager->windowResized(); mLoadingScreen->onResChange (x,y); if (!mHud) @@ -1401,4 +1411,57 @@ namespace MWGui mMap->readRecord(reader, type); } + void WindowManager::playVideo(const std::string &name, bool allowSkipping) + { + mVideoWidget->playVideo("video\\" + name, allowSkipping); + + // Turn off all rendering except for the GUI + mRendering->getScene()->clearSpecialCaseRenderQueues(); + // SCRQM_INCLUDE with RENDER_QUEUE_OVERLAY does not work? + for(int i = 0;i < Ogre::RENDER_QUEUE_MAX;++i) + { + if(i > 0 && i < 96) + mRendering->getScene()->addSpecialCaseRenderQueue(i); + } + mRendering->getScene()->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE); + + MyGUI::IntSize screenSize = MyGUI::RenderManager::getInstance().getViewSize(); + sizeVideo(screenSize.width, screenSize.height); + + setKeyFocusWidget(mVideoWidget); + + mVideoBackground->setVisible(true); + + bool cursorWasVisible = mCursorVisible; + setCursorVisible(false); + + while (mVideoWidget->update()) + { + MWBase::Environment::get().getInputManager()->update(0, false); + + mRendering->getWindow()->update(); + } + + setCursorVisible(cursorWasVisible); + + // Restore normal rendering + mRendering->getScene()->clearSpecialCaseRenderQueues(); + mRendering->getScene()->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE); + + mVideoBackground->setVisible(false); + } + + void WindowManager::sizeVideo(int screenWidth, int screenHeight) + { + // Use black bars to correct aspect ratio + mVideoBackground->setSize(screenWidth, screenHeight); + + double imageaspect = static_cast(mVideoWidget->getVideoWidth())/mVideoWidget->getVideoHeight(); + + int leftPadding = std::max(0.0, (screenWidth - screenHeight * imageaspect) / 2); + int topPadding = std::max(0.0, (screenHeight - screenWidth / imageaspect) / 2); + + mVideoWidget->setCoord(leftPadding, topPadding, + screenWidth - leftPadding*2, screenHeight - topPadding*2); + } } diff --git a/apps/openmw/mwgui/windowmanagerimp.hpp b/apps/openmw/mwgui/windowmanagerimp.hpp index dafb65e47b..ab9770a41b 100644 --- a/apps/openmw/mwgui/windowmanagerimp.hpp +++ b/apps/openmw/mwgui/windowmanagerimp.hpp @@ -18,6 +18,7 @@ namespace MyGUI class Widget; class Window; class UString; + class ImageBox; } namespace Compiler @@ -80,6 +81,7 @@ namespace MWGui class SoulgemDialog; class Recharge; class CompanionWindow; + class VideoWidget; class WindowManager : public MWBase::WindowManager { @@ -98,6 +100,10 @@ namespace MWGui virtual Loading::Listener* getLoadingScreen(); + /// @note This method will block until the video finishes playing + /// (and will continually update the window while doing so) + virtual void playVideo(const std::string& name, bool allowSkipping); + /** * Should be called each frame to update windows/gui elements. * This could mean updating sizes of gui elements or opening @@ -332,6 +338,8 @@ namespace MWGui Repair* mRepair; Recharge* mRecharge; CompanionWindow* mCompanionWindow; + MyGUI::ImageBox* mVideoBackground; + VideoWidget* mVideoWidget; Translation::Storage& mTranslationDataStorage; Cursor* mSoftwareCursor; @@ -390,6 +398,8 @@ namespace MWGui void onCursorChange(const std::string& name); void onKeyFocusChanged(MyGUI::Widget* widget); + + void sizeVideo(int screenWidth, int screenHeight); }; } diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 4bfd3f4651..840a3f71a9 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -626,9 +626,7 @@ namespace MWInput if (MyGUI::InputManager::getInstance ().isModalAny()) return; - if (MWBase::Environment::get().getWindowManager()->isGuiMode () && MWBase::Environment::get().getWindowManager()->getMode () == MWGui::GM_Video) - MWBase::Environment::get().getWorld ()->stopVideo (); - else if (MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu)) + if (MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu)) { MWBase::Environment::get().getWindowManager()->popGuiMode(); MWBase::Environment::get().getSoundManager()->resumeSounds (MWBase::SoundManager::Play_TypeSfx); diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index 15d56b8a99..fa7b17a7c1 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -43,7 +43,6 @@ #include "water.hpp" #include "npcanimation.hpp" #include "globalmap.hpp" -#include "videoplayer.hpp" #include "terrainstorage.hpp" #include "effectmanager.hpp" @@ -171,9 +170,6 @@ RenderingManager::RenderingManager(OEngine::Render::OgreRenderer& _rend, const b mOcclusionQuery = new OcclusionQuery(&mRendering, mSkyManager->getSunNode()); - mVideoPlayer = new VideoPlayer(mRendering.getScene (), mRendering.getWindow()); - mVideoPlayer->setResolution (Settings::Manager::getInt ("resolution x", "Video"), Settings::Manager::getInt ("resolution y", "Video")); - mSun = 0; mDebugging = new Debugging(mRootNode, engine); @@ -197,7 +193,6 @@ RenderingManager::~RenderingManager () delete mLocalMap; delete mOcclusionQuery; delete mWater; - delete mVideoPlayer; delete mActors; delete mObjects; delete mEffectManager; @@ -333,8 +328,6 @@ void RenderingManager::rebuildPtr(const MWWorld::Ptr &ptr) void RenderingManager::update (float duration, bool paused) { - mVideoPlayer->update (); - if (MWBase::Environment::get().getStateManager()->getState()== MWBase::StateManager::State_NoGame) return; @@ -884,8 +877,6 @@ void RenderingManager::windowResized(int x, int y) Settings::Manager::setInt("resolution y", "Video", y); mRendering.adjustViewport(); - mVideoPlayer->setResolution (x, y); - MWBase::Environment::get().getWindowManager()->windowResized(x,y); } @@ -1001,16 +992,6 @@ void RenderingManager::screenshot(Image &image, int w, int h) mRendering.getCamera()->setAspectRatio(oldAspect); } -void RenderingManager::playVideo(const std::string& name, bool allowSkipping) -{ - mVideoPlayer->playVideo ("video/" + name, allowSkipping); -} - -void RenderingManager::stopVideo() -{ - mVideoPlayer->stopVideo (); -} - void RenderingManager::addWaterRippleEmitter (const MWWorld::Ptr& ptr, float scale, float force) { mWater->addEmitter (ptr, scale, force); diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index 115a94786e..423a7078ab 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -46,7 +46,6 @@ namespace MWRender class LocalMap; class Water; class GlobalMap; - class VideoPlayer; class Animation; class EffectManager; @@ -209,8 +208,6 @@ public: Animation* getAnimation(const MWWorld::Ptr &ptr); - void playVideo(const std::string& name, bool allowSkipping); - void stopVideo(); void frameStarted(float dt, bool paused); void screenshot(Ogre::Image& image, int w, int h); @@ -271,8 +268,6 @@ private: MWRender::LocalMap* mLocalMap; MWRender::Shadows* mShadows; - - VideoPlayer* mVideoPlayer; }; } diff --git a/apps/openmw/mwrender/videoplayer.cpp b/apps/openmw/mwrender/videoplayer.cpp index 7abc8140a0..80704ca7c9 100644 --- a/apps/openmw/mwrender/videoplayer.cpp +++ b/apps/openmw/mwrender/videoplayer.cpp @@ -17,7 +17,6 @@ #include -#include "../mwbase/windowmanager.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/soundmanager.hpp" #include "../mwsound/sound_decoder.hpp" @@ -126,7 +125,7 @@ struct VideoState { int stream_open(int stream_index, AVFormatContext *pFormatCtx); - bool update(Ogre::MaterialPtr &mat, Ogre::Rectangle2D *rect, int screen_width, int screen_height); + bool update(); static void video_thread_loop(VideoState *is); static void decode_thread_loop(VideoState *is); @@ -163,6 +162,7 @@ struct VideoState { static int OgreResource_Write(void *user_data, uint8_t *buf, int buf_size); static int64_t OgreResource_Seek(void *user_data, int64_t offset, int whence); + Ogre::TexturePtr mTexture; Ogre::DataStreamPtr stream; AVFormatContext* format_ctx; @@ -599,22 +599,17 @@ void VideoState::video_display() if((*this->video_st)->codec->width != 0 && (*this->video_st)->codec->height != 0) { - Ogre::TexturePtr texture = Ogre::TextureManager::getSingleton().getByName("VideoTexture"); - if(texture.isNull() || static_cast(texture->getWidth()) != (*this->video_st)->codec->width - || static_cast(texture->getHeight()) != (*this->video_st)->codec->height) + + if(static_cast(mTexture->getWidth()) != (*this->video_st)->codec->width || + static_cast(mTexture->getHeight()) != (*this->video_st)->codec->height) { - Ogre::TextureManager::getSingleton ().remove ("VideoTexture"); - texture = Ogre::TextureManager::getSingleton().createManual( - "VideoTexture", - Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, - Ogre::TEX_TYPE_2D, - (*this->video_st)->codec->width, (*this->video_st)->codec->height, - 0, - Ogre::PF_BYTE_RGBA, - Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE); + mTexture->unload(); + mTexture->setWidth((*this->video_st)->codec->width); + mTexture->setHeight((*this->video_st)->codec->height); + mTexture->createInternalResources(); } Ogre::PixelBox pb((*this->video_st)->codec->width, (*this->video_st)->codec->height, 1, Ogre::PF_BYTE_RGBA, &vp->data[0]); - Ogre::HardwarePixelBufferSharedPtr buffer = texture->getBuffer(); + Ogre::HardwarePixelBufferSharedPtr buffer = mTexture->getBuffer(); buffer->blitFromMemory(pb); this->display_ready = true; } @@ -851,7 +846,7 @@ void VideoState::decode_thread_loop(VideoState *self) } -bool VideoState::update(Ogre::MaterialPtr &mat, Ogre::Rectangle2D *rect, int screen_width, int screen_height) +bool VideoState::update() { if(this->quit) return false; @@ -860,21 +855,6 @@ bool VideoState::update(Ogre::MaterialPtr &mat, Ogre::Rectangle2D *rect, int scr { this->refresh = false; this->video_refresh_timer(); - // Would be nice not to do this all the time... - if(this->display_ready) - mat->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName("VideoTexture"); - - // Correct aspect ratio by adding black bars - double videoaspect = av_q2d((*this->video_st)->codec->sample_aspect_ratio); - if(videoaspect == 0.0) - videoaspect = 1.0; - videoaspect *= static_cast((*this->video_st)->codec->width) / (*this->video_st)->codec->height; - - double screenaspect = static_cast(screen_width) / screen_height; - double aspect_correction = videoaspect / screenaspect; - - rect->setCorners(std::max(-1.0, -1.0 * aspect_correction), std::min( 1.0, 1.0 / aspect_correction), - std::min( 1.0, 1.0 * aspect_correction), std::max(-1.0, -1.0 / aspect_correction)); } return true; } @@ -1001,8 +981,29 @@ void VideoState::init(const std::string& resourceName) if(audio_index >= 0) this->stream_open(audio_index, this->format_ctx); if(video_index >= 0) + { this->stream_open(video_index, this->format_ctx); + int width = (*this->video_st)->codec->width; + int height = (*this->video_st)->codec->height; + static int i = 0; + this->mTexture = Ogre::TextureManager::getSingleton().createManual( + "OpenMW/VideoTexture" + Ogre::StringConverter::toString(++i), + Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME, + Ogre::TEX_TYPE_2D, + width, height, // TEST + 0, + Ogre::PF_BYTE_RGBA, + Ogre::TU_DYNAMIC_WRITE_ONLY_DISCARDABLE); + + // initialize to (0,0,0,0) + std::vector buffer; + buffer.resize(width * height, 0); + Ogre::PixelBox pb(width, height, 1, Ogre::PF_BYTE_RGBA, &buffer[0]); + this->mTexture->getBuffer()->blitFromMemory(pb); + } + + this->parse_thread = boost::thread(decode_thread_loop, this); } @@ -1073,111 +1074,26 @@ public: #endif // defined OPENMW_USE_FFMPEG -VideoPlayer::VideoPlayer(Ogre::SceneManager* sceneMgr, Ogre::RenderWindow* window) +VideoPlayer::VideoPlayer() : mState(NULL) - , mSceneMgr(sceneMgr) - , mRectangle(NULL) - , mNode(NULL) - , mAllowSkipping(false) - , mWindow(window) - , mWidth(0) - , mHeight(0) { - mVideoMaterial = Ogre::MaterialManager::getSingleton().getByName("VideoMaterial", "General"); - if (mVideoMaterial.isNull ()) - { - mVideoMaterial = Ogre::MaterialManager::getSingleton().create("VideoMaterial", "General"); - mVideoMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); - mVideoMaterial->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); - mVideoMaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false); - mVideoMaterial->getTechnique(0)->getPass(0)->createTextureUnitState(); - mVideoMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureAddressingMode(Ogre::TextureUnitState::TAM_CLAMP); - } - mVideoMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName("black.png"); - Ogre::MaterialPtr blackMaterial = Ogre::MaterialManager::getSingleton().getByName("BlackBarsMaterial", "General"); - if (blackMaterial.isNull ()) - { - blackMaterial = Ogre::MaterialManager::getSingleton().create("BlackBarsMaterial", "General"); - blackMaterial->getTechnique(0)->getPass(0)->setDepthWriteEnabled(false); - blackMaterial->getTechnique(0)->getPass(0)->setDepthCheckEnabled(false); - blackMaterial->getTechnique(0)->getPass(0)->setLightingEnabled(false); - blackMaterial->getTechnique(0)->getPass(0)->createTextureUnitState()->setTextureName("black.png"); - } - - mRectangle = new Ogre::Rectangle2D(true); - mRectangle->setCorners(-1.0, 1.0, 1.0, -1.0); - mRectangle->setMaterial("VideoMaterial"); - mRectangle->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY+2); - mBackgroundRectangle = new Ogre::Rectangle2D(true); - mBackgroundRectangle->setCorners(-1.0, 1.0, 1.0, -1.0); - mBackgroundRectangle->setMaterial("BlackBarsMaterial"); - mBackgroundRectangle->setRenderQueueGroup(Ogre::RENDER_QUEUE_OVERLAY+1); - - // Use infinite AAB to always stay visible - Ogre::AxisAlignedBox aabInf; - aabInf.setInfinite(); - mRectangle->setBoundingBox(aabInf); - mBackgroundRectangle->setBoundingBox(aabInf); - - // Attach background to the scene - mNode = sceneMgr->getRootSceneNode()->createChildSceneNode(); - mNode->attachObject(mRectangle); - mBackgroundNode = sceneMgr->getRootSceneNode()->createChildSceneNode(); - mBackgroundNode->attachObject(mBackgroundRectangle); - - mRectangle->setVisible(false); - mRectangle->setVisibilityFlags(RV_Overlay); - mBackgroundRectangle->setVisible(false); - mBackgroundRectangle->setVisibilityFlags(RV_Overlay); } VideoPlayer::~VideoPlayer() { if(mState) close(); - - mSceneMgr->destroySceneNode(mNode); - mSceneMgr->destroySceneNode(mBackgroundNode); - - delete mRectangle; - delete mBackgroundRectangle; } -void VideoPlayer::playVideo(const std::string &resourceName, bool allowSkipping) +void VideoPlayer::playVideo(const std::string &resourceName) { - mAllowSkipping = allowSkipping; - if(mState) close(); - mRectangle->setVisible(true); - mBackgroundRectangle->setVisible(true); - mVideoMaterial->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTextureName("black.png"); - - MWBase::Environment::get().getWindowManager()->pushGuiMode(MWGui::GM_Video); - - // Turn off rendering except the GUI - mSceneMgr->clearSpecialCaseRenderQueues(); - // SCRQM_INCLUDE with RENDER_QUEUE_OVERLAY does not work. - for(int i = 0;i < Ogre::RENDER_QUEUE_MAX;++i) - { - if(i > 0 && i < 96) - mSceneMgr->addSpecialCaseRenderQueue(i); - } - mSceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE); - try { mState = new VideoState; mState->init(resourceName); - - while (isPlaying()) - { - MWBase::Environment::get().getInputManager()->update(0, false); - update(); - mWindow->update(); - } - } catch(std::exception& e) { std::cerr<< "Failed to play video: "<update(mVideoMaterial, mRectangle, mWidth, mHeight)) + if(!mState->update()) close(); } } +std::string VideoPlayer::getTextureName() +{ + std::string name; + if (mState) + name = mState->mTexture->getName(); + return name; +} + +int VideoPlayer::getVideoWidth() +{ + int width=0; + if (mState) + width = mState->mTexture->getWidth(); + return width; +} + +int VideoPlayer::getVideoHeight() +{ + int height=0; + if (mState) + height = mState->mTexture->getHeight(); + return height; +} + void VideoPlayer::stopVideo () { - if (mAllowSkipping) - close(); + close(); } void VideoPlayer::close() @@ -1211,13 +1150,6 @@ void VideoPlayer::close() } MWBase::Environment::get().getSoundManager()->resumeSounds(); - - mRectangle->setVisible(false); - mBackgroundRectangle->setVisible(false); - MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Video); - - mSceneMgr->clearSpecialCaseRenderQueues(); - mSceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE); } bool VideoPlayer::isPlaying () diff --git a/apps/openmw/mwrender/videoplayer.hpp b/apps/openmw/mwrender/videoplayer.hpp index 0e548e23e4..47e252cc15 100644 --- a/apps/openmw/mwrender/videoplayer.hpp +++ b/apps/openmw/mwrender/videoplayer.hpp @@ -1,27 +1,22 @@ #ifndef VIDEOPLAYER_H #define VIDEOPLAYER_H -#include - -namespace Ogre -{ - class SceneManager; - class SceneNode; - class Rectangle2D; - class RenderWindow; -} +#include namespace MWRender { struct VideoState; + /** + * @brief Plays a video on an Ogre texture. + */ class VideoPlayer { public: - VideoPlayer(Ogre::SceneManager* sceneMgr, Ogre::RenderWindow* window); + VideoPlayer(); ~VideoPlayer(); - void playVideo (const std::string& resourceName, bool allowSkipping); + void playVideo (const std::string& resourceName); void update(); @@ -30,22 +25,14 @@ namespace MWRender bool isPlaying(); - void setResolution (int w, int h) { mWidth = w; mHeight = h; } + std::string getTextureName(); + int getVideoWidth(); + int getVideoHeight(); private: VideoState* mState; - bool mAllowSkipping; - - Ogre::SceneManager* mSceneMgr; - Ogre::MaterialPtr mVideoMaterial; - Ogre::Rectangle2D* mRectangle; - Ogre::Rectangle2D* mBackgroundRectangle; - Ogre::SceneNode* mNode; - Ogre::SceneNode* mBackgroundNode; - Ogre::RenderWindow* mWindow; - int mWidth; int mHeight; }; diff --git a/apps/openmw/mwscript/miscextensions.cpp b/apps/openmw/mwscript/miscextensions.cpp index fa8441aa57..89a5ceec1e 100644 --- a/apps/openmw/mwscript/miscextensions.cpp +++ b/apps/openmw/mwscript/miscextensions.cpp @@ -47,7 +47,7 @@ namespace MWScript bool allowSkipping = runtime[0].mInteger; runtime.pop(); - MWBase::Environment::get().getWorld ()->playVideo (name, allowSkipping); + MWBase::Environment::get().getWindowManager()->playVideo (name, allowSkipping); } }; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 62bdd38ea1..f884f69af2 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -1305,7 +1305,7 @@ namespace MWWorld { --mPlayIntro; if (mPlayIntro == 0) - mRendering->playVideo(mFallback.getFallbackString("Movies_New_Game"), true); + MWBase::Environment::get().getWindowManager()->playVideo(mFallback.getFallbackString("Movies_New_Game"), true); } if (mGoToJail && !paused) @@ -1776,16 +1776,6 @@ namespace MWWorld return mRendering->getAnimation(ptr); } - void World::playVideo (const std::string &name, bool allowSkipping) - { - mRendering->playVideo(name, allowSkipping); - } - - void World::stopVideo () - { - mRendering->stopVideo(); - } - void World::frameStarted (float dt, bool paused) { mRendering->frameStarted(dt, paused); diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 42f52cb619..f1e89bf6bc 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -523,8 +523,6 @@ namespace MWWorld virtual MWRender::Animation* getAnimation(const MWWorld::Ptr &ptr); /// \todo this does not belong here - virtual void playVideo(const std::string& name, bool allowSkipping); - virtual void stopVideo(); virtual void frameStarted (float dt, bool paused); virtual void screenshot (Ogre::Image& image, int w, int h); diff --git a/files/mygui/openmw_layers.xml b/files/mygui/openmw_layers.xml index 8bd95e2cd3..6f77369949 100644 --- a/files/mygui/openmw_layers.xml +++ b/files/mygui/openmw_layers.xml @@ -9,5 +9,6 @@ + From f2cd37edd0ee8903f0d4f2bd53214bf16a7290dd Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 27 Mar 2014 19:51:48 +0100 Subject: [PATCH 124/127] Play company logo movie --- apps/openmw/engine.cpp | 18 ++++++------------ apps/openmw/mwbase/inputmanager.hpp | 2 +- apps/openmw/mwgui/loadingscreen.cpp | 2 +- apps/openmw/mwgui/windowmanagerimp.cpp | 2 +- apps/openmw/mwinput/inputmanagerimp.cpp | 16 ++++++++-------- apps/openmw/mwinput/inputmanagerimp.hpp | 2 +- files/mygui/openmw_layers.xml | 2 +- 7 files changed, 19 insertions(+), 25 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index a118152edd..f02432ba86 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -362,14 +362,9 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) // Create sound system mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound)); - // TODO: play pre-load intro videos. Need to find a way to have them receive input. - // Make videoplayer a MyGUI widget? - /* - { - MWRender::VideoPlayer player(mOgre->getScene(), mOgre->getWindow()); - player.playVideo("mw_logo.bik", 1); - } - */ + std::string logo = mFallbackMap["Movies_Company_Logo"]; + if (!logo.empty()) + window->playVideo(logo, 1); // Create the world mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mContentFiles, @@ -453,10 +448,9 @@ void OMW::Engine::go() // Is there an ini setting for this filename or something? MWBase::Environment::get().getSoundManager()->streamMusic("Special/morrowind title.mp3"); - // TODO: there are other intro videos, too. They need to be imported from Morrowind.ini. - // Unfortunately those must play BEFORE any loading is done, which will currently not work. - // The videoplayer is created by World, so all content files must be loaded first... - MWBase::Environment::get().getWindowManager()->playVideo("mw_logo.bik", true); + std::string logo = mFallbackMap["Movies_Morrowind_Logo"]; + if (!logo.empty()) + MWBase::Environment::get().getWindowManager()->playVideo(logo, true); } catch (...) {} } diff --git a/apps/openmw/mwbase/inputmanager.hpp b/apps/openmw/mwbase/inputmanager.hpp index 42922a5b3d..d44da4974d 100644 --- a/apps/openmw/mwbase/inputmanager.hpp +++ b/apps/openmw/mwbase/inputmanager.hpp @@ -25,7 +25,7 @@ namespace MWBase virtual ~InputManager() {} - virtual void update(float dt, bool loading) = 0; + virtual void update(float dt, bool disableControls, bool disableEvents=false) = 0; virtual void changeInputMode(bool guiMode) = 0; diff --git a/apps/openmw/mwgui/loadingscreen.cpp b/apps/openmw/mwgui/loadingscreen.cpp index 37e29591b8..b3f70a5ab0 100644 --- a/apps/openmw/mwgui/loadingscreen.cpp +++ b/apps/openmw/mwgui/loadingscreen.cpp @@ -226,7 +226,7 @@ namespace MWGui } mSceneMgr->setSpecialCaseRenderQueueMode(Ogre::SceneManager::SCRQM_EXCLUDE); - MWBase::Environment::get().getInputManager()->update(0, true); + MWBase::Environment::get().getInputManager()->update(0, true, true); // First, swap buffers from last draw, then, queue an update of the // window contents, but don't swap buffers (which would have diff --git a/apps/openmw/mwgui/windowmanagerimp.cpp b/apps/openmw/mwgui/windowmanagerimp.cpp index ca8459fa1e..1e019aaa95 100644 --- a/apps/openmw/mwgui/windowmanagerimp.cpp +++ b/apps/openmw/mwgui/windowmanagerimp.cpp @@ -1437,7 +1437,7 @@ namespace MWGui while (mVideoWidget->update()) { - MWBase::Environment::get().getInputManager()->update(0, false); + MWBase::Environment::get().getInputManager()->update(0, true, false); mRendering->getWindow()->update(); } diff --git a/apps/openmw/mwinput/inputmanagerimp.cpp b/apps/openmw/mwinput/inputmanagerimp.cpp index 840a3f71a9..e2d4f8cb2d 100644 --- a/apps/openmw/mwinput/inputmanagerimp.cpp +++ b/apps/openmw/mwinput/inputmanagerimp.cpp @@ -96,12 +96,12 @@ namespace MWInput : mOgre(ogre) , mPlayer(NULL) , mEngine(engine) - , mMouseLookEnabled(true) + , mMouseLookEnabled(false) , mMouseX(ogre.getWindow()->getWidth ()/2.f) , mMouseY(ogre.getWindow()->getHeight ()/2.f) , mMouseWheel(0) , mDragDrop(false) - , mGuiCursorEnabled(false) + , mGuiCursorEnabled(true) , mUserFile(userFile) , mUserFileExists(userFileExists) , mInvertY (Settings::Manager::getBool("invert y axis", "Input")) @@ -256,18 +256,21 @@ namespace MWInput } } - void InputManager::update(float dt, bool loading) + void InputManager::update(float dt, bool disableControls, bool disableEvents) { mInputManager->setMouseVisible(MWBase::Environment::get().getWindowManager()->getCursorVisible()); - mInputManager->capture(loading); + mInputManager->capture(disableEvents); // inject some fake mouse movement to force updating MyGUI's widget states MyGUI::InputManager::getInstance().injectMouseMove( int(mMouseX), int(mMouseY), mMouseWheel); // update values of channels (as a result of pressed keys) - if (!loading) + if (!disableControls) mInputBinder->update(dt); + if (disableControls) + return; + bool grab = !MWBase::Environment::get().getWindowManager()->containsMode(MWGui::GM_MainMenu) && MWBase::Environment::get().getWindowManager()->getMode() != MWGui::GM_Console; @@ -288,9 +291,6 @@ namespace MWInput mInputManager->warpMouse(mMouseX, mMouseY); } - if (loading) - return; - // Disable movement in Gui mode if (MWBase::Environment::get().getWindowManager()->isGuiMode() || MWBase::Environment::get().getStateManager()->getState() != MWBase::StateManager::State_Running) diff --git a/apps/openmw/mwinput/inputmanagerimp.hpp b/apps/openmw/mwinput/inputmanagerimp.hpp index 2eab03a34e..87fbda25cd 100644 --- a/apps/openmw/mwinput/inputmanagerimp.hpp +++ b/apps/openmw/mwinput/inputmanagerimp.hpp @@ -68,7 +68,7 @@ namespace MWInput /// Clear all savegame-specific data virtual void clear(); - virtual void update(float dt, bool loading); + virtual void update(float dt, bool disableControls, bool disableEvents=false); void setPlayer (MWWorld::Player* player) { mPlayer = player; } diff --git a/files/mygui/openmw_layers.xml b/files/mygui/openmw_layers.xml index 6f77369949..e66f3fc017 100644 --- a/files/mygui/openmw_layers.xml +++ b/files/mygui/openmw_layers.xml @@ -9,6 +9,6 @@ - + From 4f852daf45cfd9ee5e199edd25b924909e08f103 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 27 Mar 2014 19:59:33 +0100 Subject: [PATCH 125/127] Don't play company logo when using --skip-menu --- apps/openmw/engine.cpp | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index f02432ba86..508b195e92 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -362,9 +362,12 @@ void OMW::Engine::prepareEngine (Settings::Manager & settings) // Create sound system mEnvironment.setSoundManager (new MWSound::SoundManager(mUseSound)); - std::string logo = mFallbackMap["Movies_Company_Logo"]; - if (!logo.empty()) - window->playVideo(logo, 1); + if (!mSkipMenu) + { + std::string logo = mFallbackMap["Movies_Company_Logo"]; + if (!logo.empty()) + window->playVideo(logo, 1); + } // Create the world mEnvironment.setWorld( new MWWorld::World (*mOgre, mFileCollections, mContentFiles, From ea357cfed086154766808d54da9d62db9da9eb14 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 27 Mar 2014 20:39:56 +0100 Subject: [PATCH 126/127] Fix crash when resizing while company logo is playing --- libs/openengine/ogre/renderer.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index c816f2060c..5f95789884 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -157,5 +157,6 @@ void OgreRenderer::setFov(float fov) void OgreRenderer::windowResized(int x, int y) { - mWindowListener->windowResized(x,y); + if (mWindowListener) + mWindowListener->windowResized(x,y); } From d7df9cae21dd4946901f01769a5f4f702cc01d09 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 27 Mar 2014 22:32:42 +0100 Subject: [PATCH 127/127] Bug #1224: Changed fix to potentially allow for language independent saves --- apps/openmw/mwgui/savegamedialog.cpp | 16 +++++++++++++++- apps/openmw/mwstate/statemanagerimp.cpp | 7 ++++++- apps/openmw/mwworld/store.hpp | 8 ++++++++ components/esm/savedgame.cpp | 12 ++++++++++-- components/esm/savedgame.hpp | 11 ++++++----- 5 files changed, 45 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwgui/savegamedialog.cpp b/apps/openmw/mwgui/savegamedialog.cpp index 6971358c17..caa082646e 100644 --- a/apps/openmw/mwgui/savegamedialog.cpp +++ b/apps/openmw/mwgui/savegamedialog.cpp @@ -86,7 +86,21 @@ namespace MWGui { std::stringstream title; title << it->getSignature().mPlayerName; - title << " (Level " << it->getSignature().mPlayerLevel << " " << it->getSignature().mPlayerClassName << ")"; + + // For a custom class, we will not find it in the store (unless we loaded the savegame first). + // Fall back to name stored in savegame header in that case. + std::string className; + if (it->getSignature().mPlayerClassId.empty()) + className = it->getSignature().mPlayerClassName; + else + { + // Find the localised name for this class from the store + const ESM::Class* class_ = MWBase::Environment::get().getWorld()->getStore().get().find( + it->getSignature().mPlayerClassId); + className = class_->mName; + } + + title << " (Level " << it->getSignature().mPlayerLevel << " " << className << ")"; mCharacterSelection->addItem (title.str()); diff --git a/apps/openmw/mwstate/statemanagerimp.cpp b/apps/openmw/mwstate/statemanagerimp.cpp index a0d482f0a0..7793cc9608 100644 --- a/apps/openmw/mwstate/statemanagerimp.cpp +++ b/apps/openmw/mwstate/statemanagerimp.cpp @@ -155,7 +155,12 @@ void MWState::StateManager::saveGame (const std::string& description, const Slot profile.mPlayerName = player.getClass().getName (player); profile.mPlayerLevel = player.getClass().getNpcStats (player).getLevel(); - profile.mPlayerClassName = world.getStore().get().find(player.get()->mBase->mClass)->mName; + + std::string classId = player.get()->mBase->mClass; + if (world.getStore().get().isDynamic(classId)) + profile.mPlayerClassName = world.getStore().get().find(classId)->mName; + else + profile.mPlayerClassId = classId; profile.mPlayerCell = world.getCellName(); diff --git a/apps/openmw/mwworld/store.hpp b/apps/openmw/mwworld/store.hpp index 6b99c0a0c4..0fc2d547cb 100644 --- a/apps/openmw/mwworld/store.hpp +++ b/apps/openmw/mwworld/store.hpp @@ -157,6 +157,14 @@ namespace MWWorld return 0; } + /** + * Does the record with this ID come from the dynamic store? + */ + bool isDynamic(const std::string &id) const { + typename Dynamic::const_iterator dit = mDynamic.find(id); + return (dit != mDynamic.end()); + } + /** Returns a random record that starts with the named ID, or NULL if not found. */ const T *searchRandom(const std::string &id) const { diff --git a/components/esm/savedgame.cpp b/components/esm/savedgame.cpp index 813865e253..b5e0810dbc 100644 --- a/components/esm/savedgame.cpp +++ b/components/esm/savedgame.cpp @@ -11,7 +11,10 @@ void ESM::SavedGame::load (ESMReader &esm) { mPlayerName = esm.getHNString("PLNA"); esm.getHNOT (mPlayerLevel, "PLLE"); - mPlayerClassName = esm.getHNString("PLCL"); + + mPlayerClassId = esm.getHNOString("PLCL"); + mPlayerClassName = esm.getHNOString("PLCN"); + mPlayerCell = esm.getHNString("PLCE"); esm.getHNT (mInGameTime, "TSTM", 16); esm.getHNT (mTimePlayed, "TIME"); @@ -30,7 +33,12 @@ void ESM::SavedGame::save (ESMWriter &esm) const { esm.writeHNString ("PLNA", mPlayerName); esm.writeHNT ("PLLE", mPlayerLevel); - esm.writeHNString ("PLCL", mPlayerClassName); + + if (!mPlayerClassId.empty()) + esm.writeHNString ("PLCL", mPlayerClassId); + else + esm.writeHNString ("PLCN", mPlayerClassName); + esm.writeHNString ("PLCE", mPlayerCell); esm.writeHNT ("TSTM", mInGameTime, 16); esm.writeHNT ("TIME", mTimePlayed); diff --git a/components/esm/savedgame.hpp b/components/esm/savedgame.hpp index b8615a6bc4..3e7cae775a 100644 --- a/components/esm/savedgame.hpp +++ b/components/esm/savedgame.hpp @@ -26,12 +26,13 @@ namespace ESM std::vector mContentFiles; std::string mPlayerName; int mPlayerLevel; - // The (translated) name of the player class. So it will be displayed in the MW language - // the savegame was made in, not the currently running language of MW. - // However, savegames from a different MW language are not compatible anyway. - // And if only the ID was stored here, we would need to - // peek into the savegame to look for a class record in case it is a custom class. + + // ID of class + std::string mPlayerClassId; + // Name of the class. When using a custom class, the ID is not really meaningful prior + // to loading the savegame, so the name is stored separately. std::string mPlayerClassName; + std::string mPlayerCell; TimeStamp mInGameTime; double mTimePlayed;