From e9f14449eb9286425a3f0e6cc8306a78bdf803a1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 10 Sep 2013 16:45:01 +0200 Subject: [PATCH] added AdjusterWidget --- apps/opencs/CMakeLists.txt | 1 + apps/opencs/editor.cpp | 29 ++++---- apps/opencs/editor.hpp | 2 +- apps/opencs/model/doc/document.cpp | 15 ++-- apps/opencs/model/doc/document.hpp | 9 ++- apps/opencs/model/doc/documentmanager.cpp | 4 +- apps/opencs/model/doc/documentmanager.hpp | 3 +- apps/opencs/view/doc/adjusterwidget.cpp | 90 +++++++++++++++++++++++ apps/opencs/view/doc/adjusterwidget.hpp | 41 +++++++++++ apps/opencs/view/doc/filewidget.cpp | 3 +- apps/opencs/view/doc/filewidget.hpp | 4 +- apps/opencs/view/doc/newgame.cpp | 16 +++- apps/opencs/view/doc/newgame.hpp | 11 ++- apps/opencs/view/doc/view.cpp | 2 +- 14 files changed, 190 insertions(+), 40 deletions(-) create mode 100644 apps/opencs/view/doc/adjusterwidget.cpp create mode 100644 apps/opencs/view/doc/adjusterwidget.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 916ae6e24..aa6f6ba76 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -44,6 +44,7 @@ opencs_units_noqt (model/tools opencs_units (view/doc viewmanager view operations operation subview startup filedialog newgame filewidget + adjusterwidget ) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 09e80d73b..9a6832ec0 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -9,10 +9,15 @@ #include "model/doc/document.hpp" #include "model/world/data.hpp" + CS::Editor::Editor() : mViewManager (mDocumentManager) { mIpcServerName = "org.openmw.OpenCS"; + setupDataFiles(); + + mNewGame.setLocalData (mLocal); + connect (&mViewManager, SIGNAL (newGameRequest ()), this, SLOT (createGame ())); connect (&mViewManager, SIGNAL (newAddonRequest ()), this, SLOT (createAddon ())); connect (&mViewManager, SIGNAL (loadDocumentRequest ()), this, SLOT (loadDocument ())); @@ -26,10 +31,8 @@ CS::Editor::Editor() : mViewManager (mDocumentManager) connect (&mFileDialog, SIGNAL(openFiles()), this, SLOT(openFiles())); connect (&mFileDialog, SIGNAL(createNewFile()), this, SLOT(createNewFile())); - connect (&mNewGame, SIGNAL (createRequest (const QString&)), - this, SLOT (createNewGame (const QString&))); - - setupDataFiles(); + connect (&mNewGame, SIGNAL (createRequest (const boost::filesystem::path&)), + this, SLOT (createNewGame (const boost::filesystem::path&))); } void CS::Editor::setupDataFiles() @@ -126,7 +129,9 @@ void CS::Editor::openFiles() files.push_back(path.toStdString()); } - CSMDoc::Document *document = mDocumentManager.addDocument(files, false); + /// \todo Get the save path from the file dialogue + + CSMDoc::Document *document = mDocumentManager.addDocument (files, *files.rbegin(), false); mViewManager.addView (document); mFileDialog.hide(); @@ -143,23 +148,21 @@ void CS::Editor::createNewFile() files.push_back(mFileDialog.fileName().toStdString()); - CSMDoc::Document *document = mDocumentManager.addDocument (files, true); + /// \todo Get the save path from the file dialogue. + + CSMDoc::Document *document = mDocumentManager.addDocument (files, *files.rbegin(), true); mViewManager.addView (document); mFileDialog.hide(); } -void CS::Editor::createNewGame (const QString& file) +void CS::Editor::createNewGame (const boost::filesystem::path& file) { - boost::filesystem::path path (mLocal); - - path /= file.toUtf8().data(); - std::vector files; - files.push_back (path); + files.push_back (file); - CSMDoc::Document *document = mDocumentManager.addDocument (files, true); + CSMDoc::Document *document = mDocumentManager.addDocument (files, file, true); mViewManager.addView (document); diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index d9e1ca6bc..c83b2a685 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -61,7 +61,7 @@ namespace CS void loadDocument(); void openFiles(); void createNewFile(); - void createNewGame (const QString& file); + void createNewGame (const boost::filesystem::path& file); void showStartup(); diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 30e9c21d1..d7138f671 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -2139,18 +2139,13 @@ void CSMDoc::Document::createBase() } } -CSMDoc::Document::Document (const std::vector& files, bool new_) -: mTools (mData) +CSMDoc::Document::Document (const std::vector& files, + const boost::filesystem::path& savePath, bool new_) +: mSavePath (savePath), mTools (mData) { if (files.empty()) throw std::runtime_error ("Empty content file sequence"); - /// \todo adjust last file name: - /// \li make sure it is located in the data-local directory (adjust path if necessary) - /// \li make sure the extension matches the new scheme (change it if necesarry) - - mName = files.back().filename().string(); - if (new_ && files.size()==1) createBase(); else @@ -2201,9 +2196,9 @@ int CSMDoc::Document::getState() const return state; } -const std::string& CSMDoc::Document::getName() const +const boost::filesystem::path& CSMDoc::Document::getSavePath() const { - return mName; + return mSavePath; } void CSMDoc::Document::save() diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 1c6d9db2a..3532721ea 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -31,7 +31,7 @@ namespace CSMDoc private: - std::string mName; ///< \todo replace name with ESX list + boost::filesystem::path mSavePath; CSMWorld::Data mData; CSMTools::Tools mTools; @@ -64,15 +64,16 @@ namespace CSMDoc public: - Document (const std::vector& files, bool new_); + Document (const std::vector& files, + const boost::filesystem::path& savePath, bool new_); + ~Document(); QUndoStack& getUndoStack(); int getState() const; - const std::string& getName() const; - ///< \todo replace with ESX list + const boost::filesystem::path& getSavePath() const; void save(); diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index 740c0b582..b079109ea 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -14,10 +14,10 @@ CSMDoc::DocumentManager::~DocumentManager() delete *iter; } -CSMDoc::Document *CSMDoc::DocumentManager::addDocument (const std::vector& files, +CSMDoc::Document *CSMDoc::DocumentManager::addDocument (const std::vector& files, const boost::filesystem::path& savePath, bool new_) { - Document *document = new Document (files, new_); + Document *document = new Document (files, savePath, new_); mDocuments.push_back (document); diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index a307b76a5..dfded8d5c 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -23,7 +23,8 @@ namespace CSMDoc ~DocumentManager(); - Document *addDocument (const std::vector& files, bool new_); + Document *addDocument (const std::vector& files, + const boost::filesystem::path& savePath, bool new_); ///< The ownership of the returned document is not transferred to the caller. /// /// \param new_ Do not load the last content file in \a files and instead create in an diff --git a/apps/opencs/view/doc/adjusterwidget.cpp b/apps/opencs/view/doc/adjusterwidget.cpp new file mode 100644 index 000000000..24e37b0f5 --- /dev/null +++ b/apps/opencs/view/doc/adjusterwidget.cpp @@ -0,0 +1,90 @@ + +#include "adjusterwidget.hpp" + +#include + +#include + +#include +#include +#include + +CSVDoc::AdjusterWidget::AdjusterWidget (QWidget *parent) +: QWidget (parent), mValid (false) +{ + QHBoxLayout *layout = new QHBoxLayout (this); + + mIcon = new QLabel (this); + + layout->addWidget (mIcon, 0); + + mMessage = new QLabel (this); + mMessage->setWordWrap (true); + mMessage->setSizePolicy (QSizePolicy (QSizePolicy::Minimum, QSizePolicy::Minimum)); + + layout->addWidget (mMessage, 1); + + setName ("", false); + + setLayout (layout); +} + +void CSVDoc::AdjusterWidget::setLocalData (const boost::filesystem::path& localData) +{ + mLocalData = localData; +} + +boost::filesystem::path CSVDoc::AdjusterWidget::getPath() const +{ + if (!mValid) + throw std::logic_error ("invalid content file path"); + + return mResultPath; +} + +void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon) +{ + QString message; + + if (name.isEmpty()) + { + mValid = false; + message = "No name."; + } + else + { + boost::filesystem::path path (name.toUtf8().data()); + + path.replace_extension (addon ? ".omwaddon" : ".omwgame"); + + if (path.parent_path().string()==mLocalData.string()) + { + // path already points to the local data directory + message = QString::fromUtf8 (("Will be saved as: " + path.native()).c_str()); + mResultPath = path; + mValid = true; + } + else + { + // path points somewhere else or is a leaf name. + path = mLocalData / path.filename(); + + message = QString::fromUtf8 (("Will be saved as: " + path.native()).c_str()); + mResultPath = path; + mValid = true; + + if (boost::filesystem::exists (path)) + { + /// \todo add an user setting to make this an error. + message += "

But a file with the same name already exists. If you continue, it will be overwritten."; + } + } + } + + mMessage->setText (message); + mIcon->setPixmap (style()->standardIcon ( + mValid ? QStyle::SP_MessageBoxInformation : QStyle::SP_MessageBoxWarning). + pixmap (QSize (16, 16))); + + emit stateChanged (mValid); +} \ No newline at end of file diff --git a/apps/opencs/view/doc/adjusterwidget.hpp b/apps/opencs/view/doc/adjusterwidget.hpp new file mode 100644 index 000000000..f578dc4ae --- /dev/null +++ b/apps/opencs/view/doc/adjusterwidget.hpp @@ -0,0 +1,41 @@ +#ifndef CSV_DOC_ADJUSTERWIDGET_H +#define CSV_DOC_ADJUSTERWIDGET_H + +#include + +#include + +class QLabel; + +namespace CSVDoc +{ + class AdjusterWidget : public QWidget + { + Q_OBJECT + + boost::filesystem::path mLocalData; + QLabel *mMessage; + QLabel *mIcon; + bool mValid; + boost::filesystem::path mResultPath; + + public: + + AdjusterWidget (QWidget *parent = 0); + + void setLocalData (const boost::filesystem::path& localData); + + boost::filesystem::path getPath() const; + ///< This function must not be called if there is no valid path. + + public slots: + + void setName (const QString& name, bool addon); + + signals: + + void stateChanged (bool valid); + }; +} + +#endif \ No newline at end of file diff --git a/apps/opencs/view/doc/filewidget.cpp b/apps/opencs/view/doc/filewidget.cpp index bcd6b83f2..c8f33e92d 100644 --- a/apps/opencs/view/doc/filewidget.cpp +++ b/apps/opencs/view/doc/filewidget.cpp @@ -49,6 +49,5 @@ QString CSVDoc::FileWidget::getName() const void CSVDoc::FileWidget::textChanged (const QString& text) { - emit stateChanged (!text.isEmpty()); - emit nameChanged (getName()); + emit nameChanged (getName(), mAddon); } \ No newline at end of file diff --git a/apps/opencs/view/doc/filewidget.hpp b/apps/opencs/view/doc/filewidget.hpp index 58d52db92..c51c29632 100644 --- a/apps/opencs/view/doc/filewidget.hpp +++ b/apps/opencs/view/doc/filewidget.hpp @@ -33,9 +33,7 @@ namespace CSVDoc signals: - void stateChanged (bool valid); - - void nameChanged (const QString& file); + void nameChanged (const QString& file, bool addon); }; } diff --git a/apps/opencs/view/doc/newgame.cpp b/apps/opencs/view/doc/newgame.cpp index 7ff0f38dc..98681c499 100644 --- a/apps/opencs/view/doc/newgame.cpp +++ b/apps/opencs/view/doc/newgame.cpp @@ -8,6 +8,7 @@ #include #include "filewidget.hpp" +#include "adjusterwidget.hpp" CSVDoc::NewGameDialogue::NewGameDialogue() { @@ -20,6 +21,10 @@ CSVDoc::NewGameDialogue::NewGameDialogue() layout->addWidget (mFileWidget, 1); + mAdjusterWidget = new AdjusterWidget (this); + + layout->addWidget (mAdjusterWidget, 1); + QDialogButtonBox *buttons = new QDialogButtonBox (this); mCreate = new QPushButton ("Create", this); @@ -36,15 +41,22 @@ CSVDoc::NewGameDialogue::NewGameDialogue() setLayout (layout); - connect (mFileWidget, SIGNAL (stateChanged (bool)), this, SLOT (stateChanged (bool))); + connect (mAdjusterWidget, SIGNAL (stateChanged (bool)), this, SLOT (stateChanged (bool))); connect (mCreate, SIGNAL (clicked()), this, SLOT (create())); connect (cancel, SIGNAL (clicked()), this, SLOT (reject())); + connect (mFileWidget, SIGNAL (nameChanged (const QString&, bool)), + mAdjusterWidget, SLOT (setName (const QString&, bool))); QRect scr = QApplication::desktop()->screenGeometry(); QRect rect = geometry(); move (scr.center().x() - rect.center().x(), scr.center().y() - rect.center().y()); } +void CSVDoc::NewGameDialogue::setLocalData (const boost::filesystem::path& localData) +{ + mAdjusterWidget->setLocalData (localData); +} + void CSVDoc::NewGameDialogue::stateChanged (bool valid) { mCreate->setEnabled (valid); @@ -52,5 +64,5 @@ void CSVDoc::NewGameDialogue::stateChanged (bool valid) void CSVDoc::NewGameDialogue::create() { - emit createRequest (mFileWidget->getName()); + emit createRequest (mAdjusterWidget->getPath()); } diff --git a/apps/opencs/view/doc/newgame.hpp b/apps/opencs/view/doc/newgame.hpp index 5e581e417..aa97682ff 100644 --- a/apps/opencs/view/doc/newgame.hpp +++ b/apps/opencs/view/doc/newgame.hpp @@ -1,13 +1,19 @@ #ifndef CSV_DOC_NEWGAME_H #define CSV_DOC_NEWGAME_H +#include + #include +#include + +Q_DECLARE_METATYPE (boost::filesystem::path) class QPushButton; namespace CSVDoc { class FileWidget; + class AdjusterWidget; class NewGameDialogue : public QDialog { @@ -15,14 +21,17 @@ namespace CSVDoc QPushButton *mCreate; FileWidget *mFileWidget; + AdjusterWidget *mAdjusterWidget; public: NewGameDialogue(); + void setLocalData (const boost::filesystem::path& localData); + signals: - void createRequest (const QString& file); + void createRequest (const boost::filesystem::path& file); private slots: diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index b2e848aaa..7183753e1 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -184,7 +184,7 @@ void CSVDoc::View::updateTitle() { std::ostringstream stream; - stream << mDocument->getName(); + stream << mDocument->getSavePath().filename().string(); if (mDocument->getState() & CSMDoc::State_Modified) stream << " *";