From ecedb601696b7664666c6c80b75879e018bf4990 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 8 Sep 2013 12:06:28 +0200 Subject: [PATCH 1/3] splitting new game and new addon functions (new game currently not working) --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/editor.cpp | 20 ++++++++++++++++---- apps/opencs/editor.hpp | 5 ++++- apps/opencs/view/doc/newgame.cpp | 14 ++++++++++++++ apps/opencs/view/doc/newgame.hpp | 18 ++++++++++++++++++ apps/opencs/view/doc/view.cpp | 10 +++++++--- apps/opencs/view/doc/view.hpp | 4 +++- apps/opencs/view/doc/viewmanager.cpp | 4 ++-- apps/opencs/view/doc/viewmanager.hpp | 4 +++- 9 files changed, 68 insertions(+), 13 deletions(-) create mode 100644 apps/opencs/view/doc/newgame.cpp create mode 100644 apps/opencs/view/doc/newgame.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index fe0415ac0..8b9e31e3a 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -43,7 +43,7 @@ opencs_units_noqt (model/tools opencs_units (view/doc - viewmanager view operations operation subview startup filedialog + viewmanager view operations operation subview startup filedialog newgame ) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index e9a4a4089..afbe233e4 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -12,12 +12,13 @@ CS::Editor::Editor() : mViewManager (mDocumentManager) { mIpcServerName = "org.openmw.OpenCS"; - connect (&mViewManager, SIGNAL (newDocumentRequest ()), this, SLOT (createDocument ())); + connect (&mViewManager, SIGNAL (newGameRequest ()), this, SLOT (createGame ())); + connect (&mViewManager, SIGNAL (newAddonRequest ()), this, SLOT (createAddon ())); connect (&mViewManager, SIGNAL (loadDocumentRequest ()), this, SLOT (loadDocument ())); connect (&mViewManager, SIGNAL (editSettingsRequest()), this, SLOT (showSettings ())); - connect (&mStartup, SIGNAL (createGame()), this, SLOT (createDocument ())); /// \todo split - connect (&mStartup, SIGNAL (createAddon()), this, SLOT (createDocument ())); + connect (&mStartup, SIGNAL (createGame()), this, SLOT (createGame ())); + connect (&mStartup, SIGNAL (createAddon()), this, SLOT (createAddon ())); connect (&mStartup, SIGNAL (loadDocument()), this, SLOT (loadDocument ())); connect (&mStartup, SIGNAL (editConfig()), this, SLOT (showSettings ())); @@ -75,7 +76,18 @@ void CS::Editor::setupDataFiles() } -void CS::Editor::createDocument() +void CS::Editor::createGame() +{ + mStartup.hide(); + + if (mNewGame.isHidden()) + mNewGame.show(); + + mNewGame.raise(); + mNewGame.activateWindow(); +} + +void CS::Editor::createAddon() { mStartup.hide(); diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index e32d7d8e5..7d86358b3 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -16,6 +16,7 @@ #include "view/doc/viewmanager.hpp" #include "view/doc/startup.hpp" #include "view/doc/filedialog.hpp" +#include "view/doc/newgame.hpp" #include "view/settings/usersettingsdialog.hpp" @@ -29,6 +30,7 @@ namespace CS CSMDoc::DocumentManager mDocumentManager; CSVDoc::ViewManager mViewManager; CSVDoc::StartupDialogue mStartup; + CSVDoc::NewGameDialogue mNewGame; CSVSettings::UserSettingsDialog mSettings; FileDialog mFileDialog; @@ -51,7 +53,8 @@ namespace CS private slots: - void createDocument(); + void createGame(); + void createAddon(); void loadDocument(); void openFiles(); diff --git a/apps/opencs/view/doc/newgame.cpp b/apps/opencs/view/doc/newgame.cpp new file mode 100644 index 000000000..eea0823a7 --- /dev/null +++ b/apps/opencs/view/doc/newgame.cpp @@ -0,0 +1,14 @@ + +#include "newgame.hpp" + +#include +#include + +CSVDoc::NewGameDialogue::NewGameDialogue() +{ + setWindowTitle ("Create New Game"); + + QRect scr = QApplication::desktop()->screenGeometry(); + QRect rect = geometry(); + move (scr.center().x() - rect.center().x(), scr.center().y() - rect.center().y()); +} \ No newline at end of file diff --git a/apps/opencs/view/doc/newgame.hpp b/apps/opencs/view/doc/newgame.hpp new file mode 100644 index 000000000..7c9e92a76 --- /dev/null +++ b/apps/opencs/view/doc/newgame.hpp @@ -0,0 +1,18 @@ +#ifndef CSV_DOC_NEWGAME_H +#define CSV_DOC_NEWGAME_H + +#include + +namespace CSVDoc +{ + class NewGameDialogue : public QWidget + { + Q_OBJECT + + public: + + NewGameDialogue(); + }; +} + +#endif diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index ab175872f..b2e848aaa 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -27,9 +27,13 @@ void CSVDoc::View::setupFileMenu() { QMenu *file = menuBar()->addMenu (tr ("&File")); - QAction *new_ = new QAction (tr ("New"), this); - connect (new_, SIGNAL (triggered()), this, SIGNAL (newDocumentRequest())); - file->addAction (new_); + QAction *newGame = new QAction (tr ("New Game"), this); + connect (newGame, SIGNAL (triggered()), this, SIGNAL (newGameRequest())); + file->addAction (newGame); + + QAction *newAddon = new QAction (tr ("New Addon"), this); + connect (newAddon, SIGNAL (triggered()), this, SIGNAL (newAddonRequest())); + file->addAction (newAddon); QAction *open = new QAction (tr ("&Open"), this); connect (open, SIGNAL (triggered()), this, SIGNAL (loadDocumentRequest())); diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index 41e26a6ba..29a1d52f7 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -106,7 +106,9 @@ namespace CSVDoc signals: - void newDocumentRequest(); + void newGameRequest(); + + void newAddonRequest(); void loadDocumentRequest(); diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 984c81937..a5fe6d356 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -107,12 +107,12 @@ CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document) View *view = new View (*this, document, countViews (document)+1); - mViews.push_back (view); view->show(); - connect (view, SIGNAL (newDocumentRequest ()), this, SIGNAL (newDocumentRequest())); + connect (view, SIGNAL (newGameRequest ()), this, SIGNAL (newGameRequest())); + connect (view, SIGNAL (newAddonRequest ()), this, SIGNAL (newAddonRequest())); connect (view, SIGNAL (loadDocumentRequest ()), this, SIGNAL (loadDocumentRequest())); connect (view, SIGNAL (editSettingsRequest()), this, SIGNAL (editSettingsRequest())); diff --git a/apps/opencs/view/doc/viewmanager.hpp b/apps/opencs/view/doc/viewmanager.hpp index 1f4efbd2e..01f495186 100644 --- a/apps/opencs/view/doc/viewmanager.hpp +++ b/apps/opencs/view/doc/viewmanager.hpp @@ -55,7 +55,9 @@ namespace CSVDoc signals: - void newDocumentRequest(); + void newGameRequest(); + + void newAddonRequest(); void loadDocumentRequest(); From 25b7cd33eab7c8d039bdfef1d706538b166b3861 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sun, 8 Sep 2013 14:31:20 +0200 Subject: [PATCH 2/3] added FileWidget; fixed OpenCS configuration --- apps/opencs/CMakeLists.txt | 2 +- apps/opencs/editor.cpp | 54 +++++++++++++++++++---- apps/opencs/editor.hpp | 3 ++ apps/opencs/main.cpp | 4 +- apps/opencs/view/doc/filewidget.cpp | 54 +++++++++++++++++++++++ apps/opencs/view/doc/filewidget.hpp | 42 ++++++++++++++++++ apps/opencs/view/doc/newgame.cpp | 44 +++++++++++++++++- apps/opencs/view/doc/newgame.hpp | 21 ++++++++- components/files/configurationmanager.cpp | 14 +++++- components/files/configurationmanager.hpp | 4 +- 10 files changed, 225 insertions(+), 17 deletions(-) create mode 100644 apps/opencs/view/doc/filewidget.cpp create mode 100644 apps/opencs/view/doc/filewidget.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 8b9e31e3a..916ae6e24 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -43,7 +43,7 @@ opencs_units_noqt (model/tools opencs_units (view/doc - viewmanager view operations operation subview startup filedialog newgame + viewmanager view operations operation subview startup filedialog newgame filewidget ) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index afbe233e4..09e80d73b 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -4,6 +4,7 @@ #include #include #include +#include #include "model/doc/document.hpp" #include "model/world/data.hpp" @@ -25,6 +26,9 @@ 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(); } @@ -43,26 +47,39 @@ void CS::Editor::setupDataFiles() mCfgMgr.readConfiguration(variables, desc); - Files::PathContainer mDataDirs, mDataLocal; + Files::PathContainer dataDirs, dataLocal; if (!variables["data"].empty()) { - mDataDirs = Files::PathContainer(variables["data"].as()); + dataDirs = Files::PathContainer(variables["data"].as()); } std::string local = variables["data-local"].as(); if (!local.empty()) { - mDataLocal.push_back(Files::PathContainer::value_type(local)); + dataLocal.push_back(Files::PathContainer::value_type(local)); } - mCfgMgr.processPaths(mDataDirs); - mCfgMgr.processPaths(mDataLocal); + mCfgMgr.processPaths (dataDirs); + mCfgMgr.processPaths (dataLocal, true); + + if (!dataLocal.empty()) + mLocal = dataLocal[0]; + else + { + QMessageBox messageBox; + messageBox.setWindowTitle (tr ("No local data path available")); + messageBox.setIcon (QMessageBox::Critical); + messageBox.setStandardButtons (QMessageBox::Ok); + messageBox.setText(tr("
OpenCS is unable to access the local data directory. This may indicate a faulty configuration or a broken install.")); + messageBox.exec(); + + QApplication::exit (1); + return; + } // Set the charset for reading the esm/esp files QString encoding = QString::fromStdString(variables["encoding"].as()); mFileDialog.setEncoding(encoding); - Files::PathContainer dataDirs; - dataDirs.insert(dataDirs.end(), mDataDirs.begin(), mDataDirs.end()); - dataDirs.insert(dataDirs.end(), mDataLocal.begin(), mDataLocal.end()); + dataDirs.insert (dataDirs.end(), dataLocal.begin(), dataLocal.end()); for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter) { @@ -73,7 +90,6 @@ void CS::Editor::setupDataFiles() //load the settings into the userSettings instance. const QString settingFileName = "opencs.cfg"; CSMSettings::UserSettings::instance().loadSettings(settingFileName); - } void CS::Editor::createGame() @@ -133,6 +149,23 @@ void CS::Editor::createNewFile() mFileDialog.hide(); } +void CS::Editor::createNewGame (const QString& file) +{ + boost::filesystem::path path (mLocal); + + path /= file.toUtf8().data(); + + std::vector files; + + files.push_back (path); + + CSMDoc::Document *document = mDocumentManager.addDocument (files, true); + + mViewManager.addView (document); + + mNewGame.hide(); +} + void CS::Editor::showStartup() { if(mStartup.isHidden()) @@ -173,6 +206,9 @@ void CS::Editor::connectToIPCServer() int CS::Editor::run() { + if (mLocal.empty()) + return 1; + mStartup.show(); QApplication::setQuitOnLastWindowClosed (true); diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 7d86358b3..d9e1ca6bc 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -35,6 +35,8 @@ namespace CS FileDialog mFileDialog; Files::ConfigurationManager mCfgMgr; + boost::filesystem::path mLocal; + void setupDataFiles(); // not implemented @@ -59,6 +61,7 @@ namespace CS void loadDocument(); void openFiles(); void createNewFile(); + void createNewGame (const QString& file); void showStartup(); diff --git a/apps/opencs/main.cpp b/apps/opencs/main.cpp index eddeb1983..ef7123c20 100644 --- a/apps/opencs/main.cpp +++ b/apps/opencs/main.cpp @@ -41,8 +41,8 @@ int main(int argc, char *argv[]) if(!editor.makeIPCServer()) { - editor.connectToIPCServer(); - return 0; + editor.connectToIPCServer(); + return 0; } return editor.run(); diff --git a/apps/opencs/view/doc/filewidget.cpp b/apps/opencs/view/doc/filewidget.cpp new file mode 100644 index 000000000..bcd6b83f2 --- /dev/null +++ b/apps/opencs/view/doc/filewidget.cpp @@ -0,0 +1,54 @@ + +#include "filewidget.hpp" + +#include +#include +#include +#include +#include + +QString CSVDoc::FileWidget::getExtension() const +{ + return mAddon ? ".omwaddon" : ".omwgame"; +} + +CSVDoc::FileWidget::FileWidget (QWidget *parent) : QWidget (parent), mAddon (false) +{ + QHBoxLayout *layout = new QHBoxLayout (this); + + mInput = new QLineEdit (this); + mInput->setValidator (new QRegExpValidator(QRegExp("^[a-zA-Z0-9\\s]*$"))); + + layout->addWidget (mInput, 1); + + mType = new QLabel (this); + + layout ->addWidget (mType); + + connect (mInput, SIGNAL (textChanged (const QString&)), this, SLOT (textChanged (const QString&))); + + setLayout (layout); +} + +void CSVDoc::FileWidget::setType (bool addon) +{ + mAddon = addon; + + mType->setText (getExtension()); +} + +QString CSVDoc::FileWidget::getName() const +{ + QString text = mInput->text(); + + if (text.isEmpty()) + return ""; + + return text + getExtension(); +} + +void CSVDoc::FileWidget::textChanged (const QString& text) +{ + emit stateChanged (!text.isEmpty()); + emit nameChanged (getName()); +} \ No newline at end of file diff --git a/apps/opencs/view/doc/filewidget.hpp b/apps/opencs/view/doc/filewidget.hpp new file mode 100644 index 000000000..58d52db92 --- /dev/null +++ b/apps/opencs/view/doc/filewidget.hpp @@ -0,0 +1,42 @@ +#ifndef CSV_DOC_FILEWIDGET_H +#define CSV_DOC_FILEWIDGET_H + +#include + +class QLabel; +class QString; +class QLineEdit; + +namespace CSVDoc +{ + class FileWidget : public QWidget + { + Q_OBJECT + + bool mAddon; + QLineEdit *mInput; + QLabel *mType; + + QString getExtension() const; + + public: + + FileWidget (QWidget *parent = 0); + + void setType (bool addon); + + QString getName() const; + + private slots: + + void textChanged (const QString& text); + + signals: + + void stateChanged (bool valid); + + void nameChanged (const QString& file); + }; +} + +#endif diff --git a/apps/opencs/view/doc/newgame.cpp b/apps/opencs/view/doc/newgame.cpp index eea0823a7..7ff0f38dc 100644 --- a/apps/opencs/view/doc/newgame.cpp +++ b/apps/opencs/view/doc/newgame.cpp @@ -3,12 +3,54 @@ #include #include +#include +#include +#include + +#include "filewidget.hpp" CSVDoc::NewGameDialogue::NewGameDialogue() { setWindowTitle ("Create New Game"); + QVBoxLayout *layout = new QVBoxLayout (this); + + mFileWidget = new FileWidget (this); + mFileWidget->setType (false); + + layout->addWidget (mFileWidget, 1); + + QDialogButtonBox *buttons = new QDialogButtonBox (this); + + mCreate = new QPushButton ("Create", this); + mCreate->setDefault (true); + mCreate->setEnabled (false); + + buttons->addButton (mCreate, QDialogButtonBox::AcceptRole); + + QPushButton *cancel = new QPushButton ("Cancel", this); + + buttons->addButton (cancel, QDialogButtonBox::RejectRole); + + layout->addWidget (buttons); + + setLayout (layout); + + connect (mFileWidget, SIGNAL (stateChanged (bool)), this, SLOT (stateChanged (bool))); + connect (mCreate, SIGNAL (clicked()), this, SLOT (create())); + connect (cancel, SIGNAL (clicked()), this, SLOT (reject())); + QRect scr = QApplication::desktop()->screenGeometry(); QRect rect = geometry(); move (scr.center().x() - rect.center().x(), scr.center().y() - rect.center().y()); -} \ No newline at end of file +} + +void CSVDoc::NewGameDialogue::stateChanged (bool valid) +{ + mCreate->setEnabled (valid); +} + +void CSVDoc::NewGameDialogue::create() +{ + emit createRequest (mFileWidget->getName()); +} diff --git a/apps/opencs/view/doc/newgame.hpp b/apps/opencs/view/doc/newgame.hpp index 7c9e92a76..5e581e417 100644 --- a/apps/opencs/view/doc/newgame.hpp +++ b/apps/opencs/view/doc/newgame.hpp @@ -1,17 +1,34 @@ #ifndef CSV_DOC_NEWGAME_H #define CSV_DOC_NEWGAME_H -#include +#include + +class QPushButton; namespace CSVDoc { - class NewGameDialogue : public QWidget + class FileWidget; + + class NewGameDialogue : public QDialog { Q_OBJECT + QPushButton *mCreate; + FileWidget *mFileWidget; + public: NewGameDialogue(); + + signals: + + void createRequest (const QString& file); + + private slots: + + void stateChanged (bool valid); + + void create(); }; } diff --git a/components/files/configurationmanager.cpp b/components/files/configurationmanager.cpp index 56e55a98d..75c877dc5 100644 --- a/components/files/configurationmanager.cpp +++ b/components/files/configurationmanager.cpp @@ -56,7 +56,7 @@ void ConfigurationManager::readConfiguration(boost::program_options::variables_m } -void ConfigurationManager::processPaths(Files::PathContainer& dataDirs) +void ConfigurationManager::processPaths(Files::PathContainer& dataDirs, bool create) { std::string path; for (Files::PathContainer::iterator it = dataDirs.begin(); it != dataDirs.end(); ++it) @@ -94,6 +94,18 @@ void ConfigurationManager::processPaths(Files::PathContainer& dataDirs) if (!boost::filesystem::is_directory(*it)) { + if (create) + { + try + { + boost::filesystem::create_directories (*it); + } + catch (...) {} + + if (boost::filesystem::is_directory(*it)) + continue; + } + (*it).clear(); } } diff --git a/components/files/configurationmanager.hpp b/components/files/configurationmanager.hpp index 765f1cebf..4df871664 100644 --- a/components/files/configurationmanager.hpp +++ b/components/files/configurationmanager.hpp @@ -30,7 +30,9 @@ struct ConfigurationManager void readConfiguration(boost::program_options::variables_map& variables, boost::program_options::options_description& description); - void processPaths(Files::PathContainer& dataDirs); + + void processPaths(Files::PathContainer& dataDirs, bool create = false); + ///< \param create Try creating the directory, if it does not exist. /**< Fixed paths */ const boost::filesystem::path& getGlobalPath() const; From e9f14449eb9286425a3f0e6cc8306a78bdf803a1 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Tue, 10 Sep 2013 16:45:01 +0200 Subject: [PATCH 3/3] 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 << " *";