From f029a9011aea60f54ad63617cb9eaf3613ee72b0 Mon Sep 17 00:00:00 2001 From: Michal Sciubidlo Date: Sun, 27 Jan 2013 22:40:38 +0100 Subject: [PATCH 01/18] Move datafilespage to shared space. --- apps/launcher/CMakeLists.txt | 33 ------------------- apps/launcher/graphicspage.cpp | 3 +- apps/launcher/maindialog.cpp | 3 +- cmake/OpenMWMacros.cmake | 16 +++++++++ components/CMakeLists.txt | 12 ++++++- .../file_order_list}/datafilespage.cpp | 0 .../file_order_list}/datafilespage.hpp | 0 .../file_order_list}/model/datafilesmodel.cpp | 0 .../file_order_list}/model/datafilesmodel.hpp | 0 .../file_order_list}/model/esm/esmfile.cpp | 0 .../file_order_list}/model/esm/esmfile.hpp | 0 .../file_order_list}/model/modelitem.cpp | 0 .../file_order_list}/model/modelitem.hpp | 0 .../file_order_list}/utils/filedialog.cpp | 0 .../file_order_list}/utils/filedialog.hpp | 0 .../file_order_list}/utils/lineedit.cpp | 0 .../file_order_list}/utils/lineedit.hpp | 0 .../file_order_list}/utils/naturalsort.cpp | 0 .../file_order_list}/utils/naturalsort.hpp | 0 .../utils/profilescombobox.cpp | 0 .../utils/profilescombobox.hpp | 0 .../utils/textinputdialog.cpp | 0 .../utils/textinputdialog.hpp | 0 23 files changed, 30 insertions(+), 37 deletions(-) rename {apps/launcher => components/file_order_list}/datafilespage.cpp (100%) rename {apps/launcher => components/file_order_list}/datafilespage.hpp (100%) rename {apps/launcher => components/file_order_list}/model/datafilesmodel.cpp (100%) rename {apps/launcher => components/file_order_list}/model/datafilesmodel.hpp (100%) rename {apps/launcher => components/file_order_list}/model/esm/esmfile.cpp (100%) rename {apps/launcher => components/file_order_list}/model/esm/esmfile.hpp (100%) rename {apps/launcher => components/file_order_list}/model/modelitem.cpp (100%) rename {apps/launcher => components/file_order_list}/model/modelitem.hpp (100%) rename {apps/launcher => components/file_order_list}/utils/filedialog.cpp (100%) rename {apps/launcher => components/file_order_list}/utils/filedialog.hpp (100%) rename {apps/launcher => components/file_order_list}/utils/lineedit.cpp (100%) rename {apps/launcher => components/file_order_list}/utils/lineedit.hpp (100%) rename {apps/launcher => components/file_order_list}/utils/naturalsort.cpp (100%) rename {apps/launcher => components/file_order_list}/utils/naturalsort.hpp (100%) rename {apps/launcher => components/file_order_list}/utils/profilescombobox.cpp (100%) rename {apps/launcher => components/file_order_list}/utils/profilescombobox.hpp (100%) rename {apps/launcher => components/file_order_list}/utils/textinputdialog.cpp (100%) rename {apps/launcher => components/file_order_list}/utils/textinputdialog.hpp (100%) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 09beaf59de..73efb9ee51 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -1,56 +1,23 @@ set(LAUNCHER - datafilespage.cpp graphicspage.cpp main.cpp maindialog.cpp playpage.cpp - model/datafilesmodel.cpp - model/modelitem.cpp - model/esm/esmfile.cpp - - utils/filedialog.cpp - utils/naturalsort.cpp - utils/lineedit.cpp - utils/profilescombobox.cpp - utils/textinputdialog.cpp - launcher.rc ) set(LAUNCHER_HEADER - datafilespage.hpp graphicspage.hpp maindialog.hpp playpage.hpp - - model/datafilesmodel.hpp - model/modelitem.hpp - model/esm/esmfile.hpp - - utils/lineedit.hpp - utils/filedialog.hpp - utils/naturalsort.hpp - utils/profilescombobox.hpp - utils/textinputdialog.hpp - ) # Headers that must be pre-processed set(LAUNCHER_HEADER_MOC - datafilespage.hpp graphicspage.hpp maindialog.hpp playpage.hpp - - model/datafilesmodel.hpp - model/modelitem.hpp - model/esm/esmfile.hpp - - utils/lineedit.hpp - utils/filedialog.hpp - utils/profilescombobox.hpp - utils/textinputdialog.hpp ) source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER} ${LAUNCHER_HEADER_MOC}) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 2c4f3430c5..e69a8c2077 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -8,8 +8,7 @@ #include #include #include - -#include "utils/naturalsort.hpp" +#include #include "graphicspage.hpp" diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 674ccdf672..7eb31e76bb 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -1,9 +1,10 @@ #include +#include + #include "maindialog.hpp" #include "playpage.hpp" #include "graphicspage.hpp" -#include "datafilespage.hpp" MainDialog::MainDialog() { diff --git a/cmake/OpenMWMacros.cmake b/cmake/OpenMWMacros.cmake index e6f45fdb1f..398363667b 100644 --- a/cmake/OpenMWMacros.cmake +++ b/cmake/OpenMWMacros.cmake @@ -23,6 +23,22 @@ endforeach (u) source_group ("components\\${dir}" FILES ${files}) endmacro (add_component_dir) +macro (add_component_qt_dir dir) +set (files) +foreach (u ${ARGN}) +file (GLOB ALL ${CMAKE_CURRENT_SOURCE_DIR} "${dir}/${u}.[ch]pp") +foreach (f ${ALL}) +list (APPEND files "${f}") +list (APPEND COMPONENT_FILES "${f}") +endforeach (f) +file (GLOB MOC_H ${CMAKE_CURRENT_SOURCE_DIR} "${dir}/${u}.hpp") +foreach (fi ${MOC_H}) +list (APPEND COMPONENT_MOC_FILES "${fi}") +endforeach (fi) +endforeach (u) +source_group ("components\\${dir}" FILES ${files}) +endmacro (add_component_qt_dir) + macro (copy_all_files source_dir destination_dir files) foreach (f ${files}) get_filename_component(filename ${f} NAME) diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 3da09ecb8f..a6812dbb30 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -66,9 +66,19 @@ add_component_dir (translation translation ) +add_component_qt_dir (file_order_list + datafilespage model/modelitem model/datafilesmodel model/esm/esmfile + utils/filedialog utils/lineedit utils/profilescombobox utils/textinputdialog utils/naturalsort + ) + +find_package(Qt4 COMPONENTS QtCore QtGUI REQUIRED) +include(${QT_USE_FILE}) + +QT4_WRAP_CPP(MOC_SRCS ${COMPONENT_MOC_FILES}) + include_directories(${BULLET_INCLUDE_DIRS}) -add_library(components STATIC ${COMPONENT_FILES}) +add_library(components STATIC ${COMPONENT_FILES} ${MOC_SRCS}) target_link_libraries(components ${Boost_LIBRARIES} ${OGRE_LIBRARIES}) diff --git a/apps/launcher/datafilespage.cpp b/components/file_order_list/datafilespage.cpp similarity index 100% rename from apps/launcher/datafilespage.cpp rename to components/file_order_list/datafilespage.cpp diff --git a/apps/launcher/datafilespage.hpp b/components/file_order_list/datafilespage.hpp similarity index 100% rename from apps/launcher/datafilespage.hpp rename to components/file_order_list/datafilespage.hpp diff --git a/apps/launcher/model/datafilesmodel.cpp b/components/file_order_list/model/datafilesmodel.cpp similarity index 100% rename from apps/launcher/model/datafilesmodel.cpp rename to components/file_order_list/model/datafilesmodel.cpp diff --git a/apps/launcher/model/datafilesmodel.hpp b/components/file_order_list/model/datafilesmodel.hpp similarity index 100% rename from apps/launcher/model/datafilesmodel.hpp rename to components/file_order_list/model/datafilesmodel.hpp diff --git a/apps/launcher/model/esm/esmfile.cpp b/components/file_order_list/model/esm/esmfile.cpp similarity index 100% rename from apps/launcher/model/esm/esmfile.cpp rename to components/file_order_list/model/esm/esmfile.cpp diff --git a/apps/launcher/model/esm/esmfile.hpp b/components/file_order_list/model/esm/esmfile.hpp similarity index 100% rename from apps/launcher/model/esm/esmfile.hpp rename to components/file_order_list/model/esm/esmfile.hpp diff --git a/apps/launcher/model/modelitem.cpp b/components/file_order_list/model/modelitem.cpp similarity index 100% rename from apps/launcher/model/modelitem.cpp rename to components/file_order_list/model/modelitem.cpp diff --git a/apps/launcher/model/modelitem.hpp b/components/file_order_list/model/modelitem.hpp similarity index 100% rename from apps/launcher/model/modelitem.hpp rename to components/file_order_list/model/modelitem.hpp diff --git a/apps/launcher/utils/filedialog.cpp b/components/file_order_list/utils/filedialog.cpp similarity index 100% rename from apps/launcher/utils/filedialog.cpp rename to components/file_order_list/utils/filedialog.cpp diff --git a/apps/launcher/utils/filedialog.hpp b/components/file_order_list/utils/filedialog.hpp similarity index 100% rename from apps/launcher/utils/filedialog.hpp rename to components/file_order_list/utils/filedialog.hpp diff --git a/apps/launcher/utils/lineedit.cpp b/components/file_order_list/utils/lineedit.cpp similarity index 100% rename from apps/launcher/utils/lineedit.cpp rename to components/file_order_list/utils/lineedit.cpp diff --git a/apps/launcher/utils/lineedit.hpp b/components/file_order_list/utils/lineedit.hpp similarity index 100% rename from apps/launcher/utils/lineedit.hpp rename to components/file_order_list/utils/lineedit.hpp diff --git a/apps/launcher/utils/naturalsort.cpp b/components/file_order_list/utils/naturalsort.cpp similarity index 100% rename from apps/launcher/utils/naturalsort.cpp rename to components/file_order_list/utils/naturalsort.cpp diff --git a/apps/launcher/utils/naturalsort.hpp b/components/file_order_list/utils/naturalsort.hpp similarity index 100% rename from apps/launcher/utils/naturalsort.hpp rename to components/file_order_list/utils/naturalsort.hpp diff --git a/apps/launcher/utils/profilescombobox.cpp b/components/file_order_list/utils/profilescombobox.cpp similarity index 100% rename from apps/launcher/utils/profilescombobox.cpp rename to components/file_order_list/utils/profilescombobox.cpp diff --git a/apps/launcher/utils/profilescombobox.hpp b/components/file_order_list/utils/profilescombobox.hpp similarity index 100% rename from apps/launcher/utils/profilescombobox.hpp rename to components/file_order_list/utils/profilescombobox.hpp diff --git a/apps/launcher/utils/textinputdialog.cpp b/components/file_order_list/utils/textinputdialog.cpp similarity index 100% rename from apps/launcher/utils/textinputdialog.cpp rename to components/file_order_list/utils/textinputdialog.cpp diff --git a/apps/launcher/utils/textinputdialog.hpp b/components/file_order_list/utils/textinputdialog.hpp similarity index 100% rename from apps/launcher/utils/textinputdialog.hpp rename to components/file_order_list/utils/textinputdialog.hpp From ac62dd050d31066ed1c40655bd167e22ff5d2b81 Mon Sep 17 00:00:00 2001 From: Michal Sciubidlo Date: Wed, 30 Jan 2013 21:08:27 +0100 Subject: [PATCH 02/18] Rename datafilespage to datafileslist --- apps/launcher/maindialog.cpp | 20 +++++----- apps/launcher/maindialog.hpp | 4 +- components/CMakeLists.txt | 2 +- .../{datafilespage.cpp => datafileslist.cpp} | 38 +++++++++---------- .../{datafilespage.hpp => datafileslist.hpp} | 8 ++-- 5 files changed, 36 insertions(+), 36 deletions(-) rename components/file_order_list/{datafilespage.cpp => datafileslist.cpp} (97%) rename components/file_order_list/{datafilespage.hpp => datafileslist.hpp} (92%) diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 7eb31e76bb..43b8f317ab 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include "maindialog.hpp" #include "playpage.hpp" @@ -124,16 +124,16 @@ void MainDialog::createPages() { mPlayPage = new PlayPage(this); mGraphicsPage = new GraphicsPage(mCfgMgr, this); - mDataFilesPage = new DataFilesPage(mCfgMgr, this); + mDataFilesList = new DataFilesList(mCfgMgr, this); // Set the combobox of the play page to imitate the combobox on the datafilespage - mPlayPage->mProfilesComboBox->setModel(mDataFilesPage->mProfilesComboBox->model()); - mPlayPage->mProfilesComboBox->setCurrentIndex(mDataFilesPage->mProfilesComboBox->currentIndex()); + mPlayPage->mProfilesComboBox->setModel(mDataFilesList->mProfilesComboBox->model()); + mPlayPage->mProfilesComboBox->setCurrentIndex(mDataFilesList->mProfilesComboBox->currentIndex()); // Add the pages to the stacked widget mPagesWidget->addWidget(mPlayPage); mPagesWidget->addWidget(mGraphicsPage); - mPagesWidget->addWidget(mDataFilesPage); + mPagesWidget->addWidget(mDataFilesList); // Select the first page mIconWidget->setCurrentItem(mIconWidget->item(0), QItemSelectionModel::Select); @@ -142,9 +142,9 @@ void MainDialog::createPages() connect(mPlayPage->mProfilesComboBox, SIGNAL(currentIndexChanged(int)), - mDataFilesPage->mProfilesComboBox, SLOT(setCurrentIndex(int))); + mDataFilesList->mProfilesComboBox, SLOT(setCurrentIndex(int))); - connect(mDataFilesPage->mProfilesComboBox, + connect(mDataFilesList->mProfilesComboBox, SIGNAL(currentIndexChanged(int)), mPlayPage->mProfilesComboBox, SLOT(setCurrentIndex(int))); @@ -190,7 +190,7 @@ bool MainDialog::setup() } // Setup the Data Files page - if (!mDataFilesPage->setupDataFiles()) { + if (!mDataFilesList->setupDataFiles()) { return false; } @@ -208,7 +208,7 @@ void MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) void MainDialog::closeEvent(QCloseEvent *event) { // Now write all config files - mDataFilesPage->writeConfig(); + mDataFilesList->writeConfig(); mGraphicsPage->writeConfig(); // Save user settings @@ -221,7 +221,7 @@ void MainDialog::closeEvent(QCloseEvent *event) void MainDialog::play() { // First do a write of all the configs, just to be sure - mDataFilesPage->writeConfig(); + mDataFilesList->writeConfig(); mGraphicsPage->writeConfig(); // Save user settings diff --git a/apps/launcher/maindialog.hpp b/apps/launcher/maindialog.hpp index bf98011cc4..5a39c11a99 100644 --- a/apps/launcher/maindialog.hpp +++ b/apps/launcher/maindialog.hpp @@ -15,7 +15,7 @@ class QString; class PlayPage; class GraphicsPage; -class DataFilesPage; +class DataFilesList; class MainDialog : public QMainWindow { @@ -39,7 +39,7 @@ private: PlayPage *mPlayPage; GraphicsPage *mGraphicsPage; - DataFilesPage *mDataFilesPage; + DataFilesList *mDataFilesList; Files::ConfigurationManager mCfgMgr; Settings::Manager mSettings; diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index a6812dbb30..3798f66b7a 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -67,7 +67,7 @@ add_component_dir (translation ) add_component_qt_dir (file_order_list - datafilespage model/modelitem model/datafilesmodel model/esm/esmfile + datafileslist model/modelitem model/datafilesmodel model/esm/esmfile utils/filedialog utils/lineedit utils/profilescombobox utils/textinputdialog utils/naturalsort ) diff --git a/components/file_order_list/datafilespage.cpp b/components/file_order_list/datafileslist.cpp similarity index 97% rename from components/file_order_list/datafilespage.cpp rename to components/file_order_list/datafileslist.cpp index 6b0539c1dd..bf4f8cb861 100644 --- a/components/file_order_list/datafilespage.cpp +++ b/components/file_order_list/datafileslist.cpp @@ -12,7 +12,7 @@ #include "utils/naturalsort.hpp" #include "utils/textinputdialog.hpp" -#include "datafilespage.hpp" +#include "datafileslist.hpp" #include /** @@ -46,7 +46,7 @@ bool rowSmallerThan(const QModelIndex &index1, const QModelIndex &index2) return index1.row() <= index2.row(); } -DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, QWidget *parent) +DataFilesList::DataFilesList(Files::ConfigurationManager &cfg, QWidget *parent) : QWidget(parent) , mCfgMgr(cfg) { @@ -180,7 +180,7 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, QWidget *parent) setupConfig(); } -void DataFilesPage::createActions() +void DataFilesList::createActions() { // Refresh the plugins QAction *refreshAction = new QAction(tr("Refresh"), this); @@ -218,7 +218,7 @@ void DataFilesPage::createActions() } -void DataFilesPage::setupConfig() +void DataFilesList::setupConfig() { // Open our config file QString config = QString::fromStdString((mCfgMgr.getUserPath() / "launcher.cfg").string()); @@ -265,7 +265,7 @@ void DataFilesPage::setupConfig() } -void DataFilesPage::readConfig() +void DataFilesList::readConfig() { // Don't read the config if no masters are found if (mMastersModel->rowCount() < 1) @@ -340,7 +340,7 @@ void DataFilesPage::readConfig() } -bool DataFilesPage::showDataFilesWarning() +bool DataFilesList::showDataFilesWarning() { QMessageBox msgBox; @@ -381,7 +381,7 @@ bool DataFilesPage::showDataFilesWarning() return true; } -bool DataFilesPage::setupDataFiles() +bool DataFilesList::setupDataFiles() { // We use the Configuration Manager to retrieve the configuration values boost::program_options::variables_map variables; @@ -451,7 +451,7 @@ bool DataFilesPage::setupDataFiles() return true; } -void DataFilesPage::writeConfig(QString profile) +void DataFilesList::writeConfig(QString profile) { // Don't overwrite the config if no masters are found if (mMastersModel->rowCount() < 1) @@ -606,7 +606,7 @@ void DataFilesPage::writeConfig(QString profile) } -void DataFilesPage::newProfile() +void DataFilesList::newProfile() { if (mNewProfileDialog->exec() == QDialog::Accepted) { @@ -621,7 +621,7 @@ void DataFilesPage::newProfile() } } -void DataFilesPage::updateOkButton(const QString &text) +void DataFilesList::updateOkButton(const QString &text) { if (text.isEmpty()) { mNewProfileDialog->setOkButtonEnabled(false); @@ -633,7 +633,7 @@ void DataFilesPage::updateOkButton(const QString &text) : mNewProfileDialog->setOkButtonEnabled(false); } -void DataFilesPage::deleteProfile() +void DataFilesList::deleteProfile() { QString profile = mProfilesComboBox->currentText(); @@ -670,7 +670,7 @@ void DataFilesPage::deleteProfile() } } -void DataFilesPage::check() +void DataFilesList::check() { // Check the current selection if (!mPluginsTable->selectionModel()->hasSelection()) { @@ -690,7 +690,7 @@ void DataFilesPage::check() } } -void DataFilesPage::uncheck() +void DataFilesList::uncheck() { // uncheck the current selection if (!mPluginsTable->selectionModel()->hasSelection()) { @@ -710,7 +710,7 @@ void DataFilesPage::uncheck() } } -void DataFilesPage::refresh() +void DataFilesList::refresh() { mPluginsModel->sort(0); @@ -722,7 +722,7 @@ void DataFilesPage::refresh() } -void DataFilesPage::setCheckState(QModelIndex index) +void DataFilesList::setCheckState(QModelIndex index) { if (!index.isValid()) return; @@ -751,13 +751,13 @@ void DataFilesPage::setCheckState(QModelIndex index) } -void DataFilesPage::filterChanged(const QString filter) +void DataFilesList::filterChanged(const QString filter) { QRegExp regExp(filter, Qt::CaseInsensitive, QRegExp::FixedString); mPluginsProxyModel->setFilterRegExp(regExp); } -void DataFilesPage::profileChanged(const QString &previous, const QString ¤t) +void DataFilesList::profileChanged(const QString &previous, const QString ¤t) { qDebug() << "Profile is changed from: " << previous << " to " << current; // Prevent the deletion of the default profile @@ -785,7 +785,7 @@ void DataFilesPage::profileChanged(const QString &previous, const QString &curre readConfig(); } -void DataFilesPage::profileRenamed(const QString &previous, const QString ¤t) +void DataFilesList::profileRenamed(const QString &previous, const QString ¤t) { if (previous.isEmpty()) return; @@ -815,7 +815,7 @@ void DataFilesPage::profileRenamed(const QString &previous, const QString &curre readConfig(); } -void DataFilesPage::showContextMenu(const QPoint &point) +void DataFilesList::showContextMenu(const QPoint &point) { // Make sure there are plugins in the view if (!mPluginsTable->selectionModel()->hasSelection()) { diff --git a/components/file_order_list/datafilespage.hpp b/components/file_order_list/datafileslist.hpp similarity index 92% rename from components/file_order_list/datafilespage.hpp rename to components/file_order_list/datafileslist.hpp index 13668ec30e..7bb6605ab0 100644 --- a/components/file_order_list/datafilespage.hpp +++ b/components/file_order_list/datafileslist.hpp @@ -1,5 +1,5 @@ -#ifndef DATAFILESPAGE_H -#define DATAFILESPAGE_H +#ifndef DATAFILESLIST_H +#define DATAFILESLIST_H #include #include @@ -20,12 +20,12 @@ class TextInputDialog; namespace Files { struct ConfigurationManager; } -class DataFilesPage : public QWidget +class DataFilesList : public QWidget { Q_OBJECT public: - DataFilesPage(Files::ConfigurationManager& cfg, QWidget *parent = 0); + DataFilesList(Files::ConfigurationManager& cfg, QWidget *parent = 0); ProfilesComboBox *mProfilesComboBox; From 492482de7f98091a90bff0fa4471475ae281dfc4 Mon Sep 17 00:00:00 2001 From: Michal Sciubidlo Date: Fri, 1 Feb 2013 00:42:03 +0100 Subject: [PATCH 03/18] Add "open" option in opencs. --- apps/opencs/CMakeLists.txt | 4 +-- apps/opencs/view/doc/view.cpp | 29 ++++++++++++++++++- apps/opencs/view/doc/view.hpp | 5 ++++ components/file_order_list/datafileslist.cpp | 16 ++++++++++ components/file_order_list/datafileslist.hpp | 1 + .../file_order_list/model/datafilesmodel.cpp | 20 +++++++++++++ .../file_order_list/model/datafilesmodel.hpp | 1 + 7 files changed, 73 insertions(+), 3 deletions(-) diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index abbc953ca4..68b22c10ef 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -17,7 +17,7 @@ set (OPENCS_SRC view/world/table.cpp view/world/tablesubview.cpp view/world/subviews.cpp view/world/util.cpp view/world/dialoguesubview.cpp - view/tools/reportsubview.cpp view/tools/subviews.cpp + view/tools/reportsubview.cpp view/tools/subviews.cpp view/tools/opendialog.cpp ) set (OPENCS_HDR @@ -38,7 +38,7 @@ set (OPENCS_HDR view/world/table.hpp view/world/tablesubview.hpp view/world/subviews.hpp view/world/util.hpp view/world/dialoguesubview.hpp - view/tools/reportsubview.hpp view/tools/subviews.hpp + view/tools/reportsubview.hpp view/tools/subviews.hpp view/tools/opendialog.hpp ) set (OPENCS_US diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 13edb6e749..ebcb9aaa7f 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -14,6 +14,8 @@ #include "../tools/subviews.hpp" +#include "../tools/opendialog.hpp" + #include "viewmanager.hpp" #include "operations.hpp" #include "subview.hpp" @@ -31,6 +33,10 @@ void CSVDoc::View::setupFileMenu() QAction *new_ = new QAction (tr ("New"), this); connect (new_, SIGNAL (triggered()), this, SIGNAL (newDocumentRequest())); file->addAction (new_); + + mLoad = new QAction(tr ("&Load"), this); + connect (mLoad, SIGNAL (triggered()), this, SLOT (load())); + file->addAction (mLoad); mSave = new QAction (tr ("&Save"), this); connect (mSave, SIGNAL (triggered()), this, SLOT (save())); @@ -110,7 +116,7 @@ void CSVDoc::View::updateActions() } CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews) -: mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), mViewTotal (totalViews) +: mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), mViewTotal (totalViews), mOpenDialog(0) { setDockOptions (QMainWindow::AllowNestedDocks); @@ -205,6 +211,27 @@ void CSVDoc::View::save() mDocument->save(); } +void CSVDoc::View::load() +{ + if (!mOpenDialog) { + mOpenDialog = new OpenDialog(this); + connect(mOpenDialog, SIGNAL(accepted()), this, SLOT(loadNewFiles())); + } + + mOpenDialog->show(); + mOpenDialog->raise(); + mOpenDialog->activateWindow(); +} + +void CSVDoc::View::loadNewFiles() +{ + //FIXME close old files + std::vector paths; + mOpenDialog->getFileList(paths); + //FIXME load new files + +} + void CSVDoc::View::verify() { addSubView (mDocument->verify()); diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index b1dedafe92..1822522033 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -9,6 +9,7 @@ #include "subviewfactory.hpp" class QAction; +class OpenDialog; namespace CSMDoc { @@ -36,10 +37,12 @@ namespace CSVDoc QAction *mUndo; QAction *mRedo; QAction *mSave; + QAction *mLoad; QAction *mVerify; std::vector mEditingActions; Operations *mOperations; SubViewFactoryManager mSubViewFactory; + OpenDialog * mOpenDialog; // not implemented View (const View&); @@ -92,6 +95,8 @@ namespace CSVDoc void newView(); + void load(); + void loadNewFiles(); void save(); void verify(); diff --git a/components/file_order_list/datafileslist.cpp b/components/file_order_list/datafileslist.cpp index bf4f8cb861..f346407a90 100644 --- a/components/file_order_list/datafileslist.cpp +++ b/components/file_order_list/datafileslist.cpp @@ -451,6 +451,22 @@ bool DataFilesList::setupDataFiles() return true; } +void DataFilesList::getSelectedFiles(std::vector& paths) +{ + QStringList masterPaths = mMastersModel->checkedItemsPaths(); + foreach (const QString &path, masterPaths) + { + paths.push_back(path.toStdString()); + cerr << path.toStdString() << endl; + } + QStringList pluginPaths = mPluginsModel->checkedItemsPaths(); + foreach (const QString &path, pluginPaths) + { + paths.push_back(path.toStdString()); + cerr << path.toStdString() << endl; + } +} + void DataFilesList::writeConfig(QString profile) { // Don't overwrite the config if no masters are found diff --git a/components/file_order_list/datafileslist.hpp b/components/file_order_list/datafileslist.hpp index 7bb6605ab0..7bdb5e0571 100644 --- a/components/file_order_list/datafileslist.hpp +++ b/components/file_order_list/datafileslist.hpp @@ -32,6 +32,7 @@ public: void writeConfig(QString profile = QString()); bool showDataFilesWarning(); bool setupDataFiles(); + void getSelectedFiles(std::vector& paths); public slots: void setCheckState(QModelIndex index); diff --git a/components/file_order_list/model/datafilesmodel.cpp b/components/file_order_list/model/datafilesmodel.cpp index e84dbe0acc..5bb1996791 100644 --- a/components/file_order_list/model/datafilesmodel.cpp +++ b/components/file_order_list/model/datafilesmodel.cpp @@ -292,6 +292,7 @@ void DataFilesModel::addMasters(const QString &path) EsmFile *file = new EsmFile(master); file->setDates(info.lastModified(), info.lastRead()); + file->setPath(info.absoluteFilePath()); // Add the master to the table if (findItem(master) == 0) @@ -427,6 +428,25 @@ QStringList DataFilesModel::checkedItems() return list; } +QStringList DataFilesModel::checkedItemsPaths() +{ + QStringList list; + + QList::ConstIterator it; + QList::ConstIterator itEnd = mFiles.constEnd(); + + int i = 0; + for (it = mFiles.constBegin(); it != itEnd; ++it) { + EsmFile *file = item(i); + ++i; + + if (mCheckStates[file->fileName()] == Qt::Checked && mAvailableFiles.contains(file->fileName())) + list << file->path(); + } + + return list; +} + void DataFilesModel::uncheckAll() { emit layoutAboutToBeChanged(); diff --git a/components/file_order_list/model/datafilesmodel.hpp b/components/file_order_list/model/datafilesmodel.hpp index 29a770a862..adc80eac2a 100644 --- a/components/file_order_list/model/datafilesmodel.hpp +++ b/components/file_order_list/model/datafilesmodel.hpp @@ -43,6 +43,7 @@ public: QStringList checkedItems(); QStringList uncheckedItems(); + QStringList checkedItemsPaths(); Qt::CheckState checkState(const QModelIndex &index); void setCheckState(const QModelIndex &index, Qt::CheckState state); From 67a1ec51665822ea03fa89906488a7872566f5c8 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 2 Feb 2013 16:14:58 +0100 Subject: [PATCH 04/18] added provisional startup dialogue --- apps/opencs/CMakeLists.txt | 4 +-- apps/opencs/editor.cpp | 46 ++++++++++++++++++++++++++-- apps/opencs/editor.hpp | 7 ++++- apps/opencs/view/doc/startup.cpp | 20 ++++++++++++ apps/opencs/view/doc/startup.hpp | 24 +++++++++++++++ apps/opencs/view/doc/view.cpp | 4 +++ apps/opencs/view/doc/view.hpp | 2 ++ apps/opencs/view/doc/viewmanager.cpp | 1 + apps/opencs/view/doc/viewmanager.hpp | 2 ++ 9 files changed, 104 insertions(+), 6 deletions(-) create mode 100644 apps/opencs/view/doc/startup.cpp create mode 100644 apps/opencs/view/doc/startup.hpp diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index abbc953ca4..d3634a66e4 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -12,7 +12,7 @@ set (OPENCS_SRC model/tools/mandatoryid.cpp model/tools/reportmodel.cpp view/doc/viewmanager.cpp view/doc/view.cpp view/doc/operations.cpp view/doc/operation.cpp view/doc/subviewfactory.cpp - view/doc/subview.cpp + view/doc/subview.cpp view/doc/startup.cpp view/world/table.cpp view/world/tablesubview.cpp view/world/subviews.cpp view/world/util.cpp view/world/dialoguesubview.cpp @@ -33,7 +33,7 @@ set (OPENCS_HDR model/tools/mandatoryid.hpp model/tools/reportmodel.hpp view/doc/viewmanager.hpp view/doc/view.hpp view/doc/operations.hpp view/doc/operation.hpp view/doc/subviewfactory.hpp - view/doc/subview.hpp view/doc/subviewfactoryimp.hpp + view/doc/subview.hpp view/doc/subviewfactoryimp.hpp view/doc/startup.hpp view/world/table.hpp view/world/tablesubview.hpp view/world/subviews.hpp view/world/util.hpp view/world/dialoguesubview.hpp diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 1632ed220d..2340c71ee2 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -11,10 +11,19 @@ CS::Editor::Editor() : mViewManager (mDocumentManager), mNewDocumentIndex (0) { connect (&mViewManager, SIGNAL (newDocumentRequest ()), this, SLOT (createDocument ())); + connect (&mViewManager, SIGNAL (loadDocumentRequest ()), this, SLOT (loadDocument ())); + + connect (&mStartup, SIGNAL (createDocument()), this, SLOT (createDocument ())); + connect (&mStartup, SIGNAL (loadDocument()), this, SLOT (loadDocument ())); } void CS::Editor::createDocument() { + mStartup.hide(); + + /// \todo open the ESX picker instead + /// \todo remove the following code for creating initial records into the document manager + std::ostringstream stream; stream << "NewDocument" << (++mNewDocumentIndex); @@ -23,7 +32,39 @@ void CS::Editor::createDocument() static const char *sGlobals[] = { - "Day", "DaysPassed", "GameHour", "Month", "PCRace", "PCVampire", "PCWerewolf", "PCYear", 0 + "Day", "DaysPassed", "GameHour", "Month", "PCRace", "PCVampire", "PCWerewolf", "PCYear", 0 + }; + + for (int i=0; sGlobals[i]; ++i) + { + ESM::Global record; + record.mId = sGlobals[i]; + record.mValue = i==0 ? 1 : 0; + record.mType = ESM::VT_Float; + document->getData().getGlobals().add (record); + } + + document->getData().merge(); /// \todo remove once proper ESX loading is implemented + + mViewManager.addView (document); +} + +void CS::Editor::loadDocument() +{ + mStartup.hide(); + + /// \todo open the ESX picker instead + /// \todo replace the manual record creation and load the ESX files instead + + std::ostringstream stream; + + stream << "Document" << (++mNewDocumentIndex); + + CSMDoc::Document *document = mDocumentManager.addDocument (stream.str()); + + static const char *sGlobals[] = + { + "Day", "DaysPassed", "GameHour", "Month", "PCRace", "PCVampire", "PCWerewolf", "PCYear", 0 }; for (int i=0; sGlobals[i]; ++i) @@ -42,8 +83,7 @@ void CS::Editor::createDocument() int CS::Editor::run() { - /// \todo Instead of creating an empty document, open a small welcome dialogue window with buttons for new/load/recent projects - createDocument(); + mStartup.show(); return QApplication::exec(); } \ No newline at end of file diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 60f7beaf1d..0cd780f7fc 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -4,7 +4,9 @@ #include #include "model/doc/documentmanager.hpp" + #include "view/doc/viewmanager.hpp" +#include "view/doc/startup.hpp" namespace CS { @@ -16,6 +18,7 @@ namespace CS CSMDoc::DocumentManager mDocumentManager; CSVDoc::ViewManager mViewManager; + CSVDoc::StartupDialogue mStartup; // not implemented Editor (const Editor&); @@ -28,9 +31,11 @@ namespace CS int run(); ///< \return error status - public slots: + private slots: void createDocument(); + + void loadDocument(); }; } diff --git a/apps/opencs/view/doc/startup.cpp b/apps/opencs/view/doc/startup.cpp new file mode 100644 index 0000000000..7861a1c2ef --- /dev/null +++ b/apps/opencs/view/doc/startup.cpp @@ -0,0 +1,20 @@ + +#include "startup.hpp" + +#include +#include + +CSVDoc::StartupDialogue::StartupDialogue() +{ + QHBoxLayout *layout = new QHBoxLayout (this); + + QPushButton *createDocument = new QPushButton ("new", this); + connect (createDocument, SIGNAL (clicked()), this, SIGNAL (createDocument())); + layout->addWidget (createDocument); + + QPushButton *loadDocument = new QPushButton ("load", this); + connect (loadDocument, SIGNAL (clicked()), this, SIGNAL (loadDocument())); + layout->addWidget (loadDocument); + + setLayout (layout); +} \ No newline at end of file diff --git a/apps/opencs/view/doc/startup.hpp b/apps/opencs/view/doc/startup.hpp new file mode 100644 index 0000000000..f24d2a64ba --- /dev/null +++ b/apps/opencs/view/doc/startup.hpp @@ -0,0 +1,24 @@ +#ifndef CSV_DOC_STARTUP_H +#define CSV_DOC_STARTUP_H + +#include + +namespace CSVDoc +{ + class StartupDialogue : public QWidget + { + Q_OBJECT + + public: + + StartupDialogue(); + + signals: + + void createDocument(); + + void loadDocument(); + }; +} + +#endif diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 13edb6e749..d6639e59ca 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -32,6 +32,10 @@ void CSVDoc::View::setupFileMenu() connect (new_, SIGNAL (triggered()), this, SIGNAL (newDocumentRequest())); file->addAction (new_); + QAction *open = new QAction (tr ("Open"), this); + connect (open, SIGNAL (triggered()), this, SIGNAL (loadDocumentRequest())); + file->addAction (open); + mSave = new QAction (tr ("&Save"), this); connect (mSave, SIGNAL (triggered()), this, SLOT (save())); file->addAction (mSave); diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index b1dedafe92..05d7210dce 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -84,6 +84,8 @@ namespace CSVDoc void newDocumentRequest(); + void loadDocumentRequest(); + public slots: void addSubView (const CSMWorld::UniversalId& id); diff --git a/apps/opencs/view/doc/viewmanager.cpp b/apps/opencs/view/doc/viewmanager.cpp index 22847c78b7..b01b9ce342 100644 --- a/apps/opencs/view/doc/viewmanager.cpp +++ b/apps/opencs/view/doc/viewmanager.cpp @@ -57,6 +57,7 @@ CSVDoc::View *CSVDoc::ViewManager::addView (CSMDoc::Document *document) view->show(); connect (view, SIGNAL (newDocumentRequest ()), this, SIGNAL (newDocumentRequest())); + connect (view, SIGNAL (loadDocumentRequest ()), this, SIGNAL (loadDocumentRequest())); updateIndices(); diff --git a/apps/opencs/view/doc/viewmanager.hpp b/apps/opencs/view/doc/viewmanager.hpp index 5e4b1be075..91a80d4962 100644 --- a/apps/opencs/view/doc/viewmanager.hpp +++ b/apps/opencs/view/doc/viewmanager.hpp @@ -46,6 +46,8 @@ namespace CSVDoc void newDocumentRequest(); + void loadDocumentRequest(); + private slots: void documentStateChanged (int state, CSMDoc::Document *document); From 155cca0c9a23eec9db94f2e9214110029a0a4838 Mon Sep 17 00:00:00 2001 From: Michal Sciubidlo Date: Sat, 2 Feb 2013 16:25:41 +0100 Subject: [PATCH 05/18] Upload missing files. Fix folder name. Keep Qt optional. Move open dialogue from doc to tools. Rename 'load' to 'open'. Deleted wrong comment. --- apps/launcher/graphicspage.cpp | 2 +- apps/launcher/maindialog.cpp | 2 +- apps/opencs/CMakeLists.txt | 8 +++--- apps/opencs/view/doc/opendialog.cpp | 27 +++++++++++++++++++ apps/opencs/view/doc/opendialog.hpp | 17 ++++++++++++ apps/opencs/view/doc/view.cpp | 16 +++++------ apps/opencs/view/doc/view.hpp | 6 ++--- components/CMakeLists.txt | 16 ++++++----- .../datafileslist.cpp | 0 .../datafileslist.hpp | 0 .../model/datafilesmodel.cpp | 0 .../model/datafilesmodel.hpp | 0 .../model/esm/esmfile.cpp | 0 .../model/esm/esmfile.hpp | 0 .../model/modelitem.cpp | 0 .../model/modelitem.hpp | 0 .../utils/filedialog.cpp | 0 .../utils/filedialog.hpp | 0 .../utils/lineedit.cpp | 0 .../utils/lineedit.hpp | 0 .../utils/naturalsort.cpp | 0 .../utils/naturalsort.hpp | 0 .../utils/profilescombobox.cpp | 0 .../utils/profilescombobox.hpp | 0 .../utils/textinputdialog.cpp | 0 .../utils/textinputdialog.hpp | 0 26 files changed, 69 insertions(+), 25 deletions(-) create mode 100644 apps/opencs/view/doc/opendialog.cpp create mode 100644 apps/opencs/view/doc/opendialog.hpp rename components/{file_order_list => fileorderlist}/datafileslist.cpp (100%) rename components/{file_order_list => fileorderlist}/datafileslist.hpp (100%) rename components/{file_order_list => fileorderlist}/model/datafilesmodel.cpp (100%) rename components/{file_order_list => fileorderlist}/model/datafilesmodel.hpp (100%) rename components/{file_order_list => fileorderlist}/model/esm/esmfile.cpp (100%) rename components/{file_order_list => fileorderlist}/model/esm/esmfile.hpp (100%) rename components/{file_order_list => fileorderlist}/model/modelitem.cpp (100%) rename components/{file_order_list => fileorderlist}/model/modelitem.hpp (100%) rename components/{file_order_list => fileorderlist}/utils/filedialog.cpp (100%) rename components/{file_order_list => fileorderlist}/utils/filedialog.hpp (100%) rename components/{file_order_list => fileorderlist}/utils/lineedit.cpp (100%) rename components/{file_order_list => fileorderlist}/utils/lineedit.hpp (100%) rename components/{file_order_list => fileorderlist}/utils/naturalsort.cpp (100%) rename components/{file_order_list => fileorderlist}/utils/naturalsort.hpp (100%) rename components/{file_order_list => fileorderlist}/utils/profilescombobox.cpp (100%) rename components/{file_order_list => fileorderlist}/utils/profilescombobox.hpp (100%) rename components/{file_order_list => fileorderlist}/utils/textinputdialog.cpp (100%) rename components/{file_order_list => fileorderlist}/utils/textinputdialog.hpp (100%) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index e69a8c2077..dee84498c2 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -8,7 +8,7 @@ #include #include #include -#include +#include #include "graphicspage.hpp" diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 43b8f317ab..7914650fe9 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -1,6 +1,6 @@ #include -#include +#include #include "maindialog.hpp" #include "playpage.hpp" diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index 68b22c10ef..76d669e151 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -12,12 +12,12 @@ set (OPENCS_SRC model/tools/mandatoryid.cpp model/tools/reportmodel.cpp view/doc/viewmanager.cpp view/doc/view.cpp view/doc/operations.cpp view/doc/operation.cpp view/doc/subviewfactory.cpp - view/doc/subview.cpp + view/doc/subview.cpp view/doc/opendialog.cpp view/world/table.cpp view/world/tablesubview.cpp view/world/subviews.cpp view/world/util.cpp view/world/dialoguesubview.cpp - view/tools/reportsubview.cpp view/tools/subviews.cpp view/tools/opendialog.cpp + view/tools/reportsubview.cpp view/tools/subviews.cpp ) set (OPENCS_HDR @@ -33,12 +33,12 @@ set (OPENCS_HDR model/tools/mandatoryid.hpp model/tools/reportmodel.hpp view/doc/viewmanager.hpp view/doc/view.hpp view/doc/operations.hpp view/doc/operation.hpp view/doc/subviewfactory.hpp - view/doc/subview.hpp view/doc/subviewfactoryimp.hpp + view/doc/subview.hpp view/doc/subviewfactoryimp.hpp view/doc/opendialog.hpp view/world/table.hpp view/world/tablesubview.hpp view/world/subviews.hpp view/world/util.hpp view/world/dialoguesubview.hpp - view/tools/reportsubview.hpp view/tools/subviews.hpp view/tools/opendialog.hpp + view/tools/reportsubview.hpp view/tools/subviews.hpp ) set (OPENCS_US diff --git a/apps/opencs/view/doc/opendialog.cpp b/apps/opencs/view/doc/opendialog.cpp new file mode 100644 index 0000000000..f51cbadb97 --- /dev/null +++ b/apps/opencs/view/doc/opendialog.cpp @@ -0,0 +1,27 @@ +#include +#include + +#include + +#include "opendialog.hpp" + +OpenDialog::OpenDialog(QWidget * parent) : QDialog(parent) +{ + QVBoxLayout *layout = new QVBoxLayout(this); + mFileSelector = new DataFilesList(mCfgMgr, this); + layout->addWidget(mFileSelector); + mFileSelector->setupDataFiles(); + + buttonBox = new QDialogButtonBox(QDialogButtonBox::Open | QDialogButtonBox::Cancel, Qt::Horizontal, this); + connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject())); + layout->addWidget(buttonBox); + + setLayout(layout); + setWindowTitle(tr("Open")); +} + +void OpenDialog::getFileList(std::vector& paths) +{ + mFileSelector->getSelectedFiles(paths); +} diff --git a/apps/opencs/view/doc/opendialog.hpp b/apps/opencs/view/doc/opendialog.hpp new file mode 100644 index 0000000000..6355aea44f --- /dev/null +++ b/apps/opencs/view/doc/opendialog.hpp @@ -0,0 +1,17 @@ +#include +#include + +class DataFilesList; +class QDialogButtonBox; + +class OpenDialog : public QDialog { + Q_OBJECT +public: + OpenDialog(QWidget * parent = 0); + + void getFileList(std::vector& paths); +private: + DataFilesList * mFileSelector; + QDialogButtonBox * buttonBox; + Files::ConfigurationManager mCfgMgr; +}; \ No newline at end of file diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index ebcb9aaa7f..112807cca0 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -14,8 +14,7 @@ #include "../tools/subviews.hpp" -#include "../tools/opendialog.hpp" - +#include "opendialog.hpp" #include "viewmanager.hpp" #include "operations.hpp" #include "subview.hpp" @@ -34,9 +33,9 @@ void CSVDoc::View::setupFileMenu() connect (new_, SIGNAL (triggered()), this, SIGNAL (newDocumentRequest())); file->addAction (new_); - mLoad = new QAction(tr ("&Load"), this); - connect (mLoad, SIGNAL (triggered()), this, SLOT (load())); - file->addAction (mLoad); + mOpen = new QAction(tr ("&Open"), this); + connect (mOpen, SIGNAL (triggered()), this, SLOT (open())); + file->addAction (mOpen); mSave = new QAction (tr ("&Save"), this); connect (mSave, SIGNAL (triggered()), this, SLOT (save())); @@ -211,11 +210,11 @@ void CSVDoc::View::save() mDocument->save(); } -void CSVDoc::View::load() +void CSVDoc::View::open() { if (!mOpenDialog) { mOpenDialog = new OpenDialog(this); - connect(mOpenDialog, SIGNAL(accepted()), this, SLOT(loadNewFiles())); + connect(mOpenDialog, SIGNAL(accepted()), this, SLOT(openNewFiles())); } mOpenDialog->show(); @@ -223,9 +222,8 @@ void CSVDoc::View::load() mOpenDialog->activateWindow(); } -void CSVDoc::View::loadNewFiles() +void CSVDoc::View::openNewFiles() { - //FIXME close old files std::vector paths; mOpenDialog->getFileList(paths); //FIXME load new files diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index 1822522033..839edf0a55 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -37,7 +37,7 @@ namespace CSVDoc QAction *mUndo; QAction *mRedo; QAction *mSave; - QAction *mLoad; + QAction *mOpen; QAction *mVerify; std::vector mEditingActions; Operations *mOperations; @@ -95,8 +95,8 @@ namespace CSVDoc void newView(); - void load(); - void loadNewFiles(); + void open(); + void openNewFiles(); void save(); void verify(); diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 3798f66b7a..63a2276217 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -66,15 +66,17 @@ add_component_dir (translation translation ) -add_component_qt_dir (file_order_list - datafileslist model/modelitem model/datafilesmodel model/esm/esmfile - utils/filedialog utils/lineedit utils/profilescombobox utils/textinputdialog utils/naturalsort - ) +find_package(Qt4 COMPONENTS QtCore QtGui) -find_package(Qt4 COMPONENTS QtCore QtGUI REQUIRED) -include(${QT_USE_FILE}) +if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) + add_component_qt_dir (fileorderlist + datafileslist model/modelitem model/datafilesmodel model/esm/esmfile + utils/filedialog utils/lineedit utils/profilescombobox utils/textinputdialog utils/naturalsort + ) -QT4_WRAP_CPP(MOC_SRCS ${COMPONENT_MOC_FILES}) + include(${QT_USE_FILE}) + QT4_WRAP_CPP(MOC_SRCS ${COMPONENT_MOC_FILES}) +endif(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) include_directories(${BULLET_INCLUDE_DIRS}) diff --git a/components/file_order_list/datafileslist.cpp b/components/fileorderlist/datafileslist.cpp similarity index 100% rename from components/file_order_list/datafileslist.cpp rename to components/fileorderlist/datafileslist.cpp diff --git a/components/file_order_list/datafileslist.hpp b/components/fileorderlist/datafileslist.hpp similarity index 100% rename from components/file_order_list/datafileslist.hpp rename to components/fileorderlist/datafileslist.hpp diff --git a/components/file_order_list/model/datafilesmodel.cpp b/components/fileorderlist/model/datafilesmodel.cpp similarity index 100% rename from components/file_order_list/model/datafilesmodel.cpp rename to components/fileorderlist/model/datafilesmodel.cpp diff --git a/components/file_order_list/model/datafilesmodel.hpp b/components/fileorderlist/model/datafilesmodel.hpp similarity index 100% rename from components/file_order_list/model/datafilesmodel.hpp rename to components/fileorderlist/model/datafilesmodel.hpp diff --git a/components/file_order_list/model/esm/esmfile.cpp b/components/fileorderlist/model/esm/esmfile.cpp similarity index 100% rename from components/file_order_list/model/esm/esmfile.cpp rename to components/fileorderlist/model/esm/esmfile.cpp diff --git a/components/file_order_list/model/esm/esmfile.hpp b/components/fileorderlist/model/esm/esmfile.hpp similarity index 100% rename from components/file_order_list/model/esm/esmfile.hpp rename to components/fileorderlist/model/esm/esmfile.hpp diff --git a/components/file_order_list/model/modelitem.cpp b/components/fileorderlist/model/modelitem.cpp similarity index 100% rename from components/file_order_list/model/modelitem.cpp rename to components/fileorderlist/model/modelitem.cpp diff --git a/components/file_order_list/model/modelitem.hpp b/components/fileorderlist/model/modelitem.hpp similarity index 100% rename from components/file_order_list/model/modelitem.hpp rename to components/fileorderlist/model/modelitem.hpp diff --git a/components/file_order_list/utils/filedialog.cpp b/components/fileorderlist/utils/filedialog.cpp similarity index 100% rename from components/file_order_list/utils/filedialog.cpp rename to components/fileorderlist/utils/filedialog.cpp diff --git a/components/file_order_list/utils/filedialog.hpp b/components/fileorderlist/utils/filedialog.hpp similarity index 100% rename from components/file_order_list/utils/filedialog.hpp rename to components/fileorderlist/utils/filedialog.hpp diff --git a/components/file_order_list/utils/lineedit.cpp b/components/fileorderlist/utils/lineedit.cpp similarity index 100% rename from components/file_order_list/utils/lineedit.cpp rename to components/fileorderlist/utils/lineedit.cpp diff --git a/components/file_order_list/utils/lineedit.hpp b/components/fileorderlist/utils/lineedit.hpp similarity index 100% rename from components/file_order_list/utils/lineedit.hpp rename to components/fileorderlist/utils/lineedit.hpp diff --git a/components/file_order_list/utils/naturalsort.cpp b/components/fileorderlist/utils/naturalsort.cpp similarity index 100% rename from components/file_order_list/utils/naturalsort.cpp rename to components/fileorderlist/utils/naturalsort.cpp diff --git a/components/file_order_list/utils/naturalsort.hpp b/components/fileorderlist/utils/naturalsort.hpp similarity index 100% rename from components/file_order_list/utils/naturalsort.hpp rename to components/fileorderlist/utils/naturalsort.hpp diff --git a/components/file_order_list/utils/profilescombobox.cpp b/components/fileorderlist/utils/profilescombobox.cpp similarity index 100% rename from components/file_order_list/utils/profilescombobox.cpp rename to components/fileorderlist/utils/profilescombobox.cpp diff --git a/components/file_order_list/utils/profilescombobox.hpp b/components/fileorderlist/utils/profilescombobox.hpp similarity index 100% rename from components/file_order_list/utils/profilescombobox.hpp rename to components/fileorderlist/utils/profilescombobox.hpp diff --git a/components/file_order_list/utils/textinputdialog.cpp b/components/fileorderlist/utils/textinputdialog.cpp similarity index 100% rename from components/file_order_list/utils/textinputdialog.cpp rename to components/fileorderlist/utils/textinputdialog.cpp diff --git a/components/file_order_list/utils/textinputdialog.hpp b/components/fileorderlist/utils/textinputdialog.hpp similarity index 100% rename from components/file_order_list/utils/textinputdialog.hpp rename to components/fileorderlist/utils/textinputdialog.hpp From 4c973a0f6767570a4ed07d0265fe949e7f0f7beb Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 4 Feb 2013 13:46:54 +0100 Subject: [PATCH 06/18] constructing documents from a file list instead of a single name --- apps/opencs/editor.cpp | 12 +++++-- apps/opencs/model/doc/document.cpp | 42 +++++++++++++++++++++-- apps/opencs/model/doc/document.hpp | 10 ++++-- apps/opencs/model/doc/documentmanager.cpp | 5 +-- apps/opencs/model/doc/documentmanager.hpp | 7 +++- 5 files changed, 66 insertions(+), 10 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 2340c71ee2..57e31e19ea 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -22,13 +22,16 @@ void CS::Editor::createDocument() mStartup.hide(); /// \todo open the ESX picker instead - /// \todo remove the following code for creating initial records into the document manager + /// \todo move the following code for creating initial records into the document manager std::ostringstream stream; stream << "NewDocument" << (++mNewDocumentIndex); - CSMDoc::Document *document = mDocumentManager.addDocument (stream.str()); + std::vector files; + files.push_back (stream.str()); + + CSMDoc::Document *document = mDocumentManager.addDocument (files, true); static const char *sGlobals[] = { @@ -60,7 +63,10 @@ void CS::Editor::loadDocument() stream << "Document" << (++mNewDocumentIndex); - CSMDoc::Document *document = mDocumentManager.addDocument (stream.str()); + std::vector files; + files.push_back (stream.str()); + + CSMDoc::Document *document = mDocumentManager.addDocument (files, false); static const char *sGlobals[] = { diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 9d26944832..93d664314e 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -1,10 +1,48 @@ #include "document.hpp" -CSMDoc::Document::Document (const std::string& name) +#include + +void CSMDoc::Document::load (const std::vector::const_iterator& begin, + const std::vector::const_iterator& end) +{ + for (std::vector::const_iterator iter (begin); iter!=end; ++iter) + std::cout << "pretending to load " << iter->string() << std::endl; + + /// \todo load content files +} + +void CSMDoc::Document::createBase() +{ + std::cout << "pretending to create base file records" << std::endl; + + /// \todo create mandatory records for base content file +} + +CSMDoc::Document::Document (const std::vector& files, bool new_) : mTools (mData) { - mName = name; ///< \todo replace with ESX list + 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 (files.size()>1 || !new_) + { + std::vector::const_iterator end = files.end(); + + if (new_) + --end; + + load (files.begin(), end); + } + + if (new_ && files.size()==1) + createBase(); connect (&mUndoStack, SIGNAL (cleanChanged (bool)), this, SLOT (modificationStateChanged (bool))); diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 43e8bba37b..28cc19d449 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -3,6 +3,8 @@ #include +#include + #include #include #include @@ -38,10 +40,14 @@ namespace CSMDoc Document (const Document&); Document& operator= (const Document&); + void load (const std::vector::const_iterator& begin, + const std::vector::const_iterator& end); + + void createBase(); + public: - Document (const std::string& name); - ///< \todo replace name with ESX list + Document (const std::vector& files, bool new_); QUndoStack& getUndoStack(); diff --git a/apps/opencs/model/doc/documentmanager.cpp b/apps/opencs/model/doc/documentmanager.cpp index 8ae2764f24..740c0b5827 100644 --- a/apps/opencs/model/doc/documentmanager.cpp +++ b/apps/opencs/model/doc/documentmanager.cpp @@ -14,9 +14,10 @@ CSMDoc::DocumentManager::~DocumentManager() delete *iter; } -CSMDoc::Document *CSMDoc::DocumentManager::addDocument (const std::string& name) +CSMDoc::Document *CSMDoc::DocumentManager::addDocument (const std::vector& files, + bool new_) { - Document *document = new Document (name); + Document *document = new Document (files, new_); mDocuments.push_back (document); diff --git a/apps/opencs/model/doc/documentmanager.hpp b/apps/opencs/model/doc/documentmanager.hpp index 730c7fae1d..a307b76a57 100644 --- a/apps/opencs/model/doc/documentmanager.hpp +++ b/apps/opencs/model/doc/documentmanager.hpp @@ -4,6 +4,8 @@ #include #include +#include + namespace CSMDoc { class Document; @@ -21,8 +23,11 @@ namespace CSMDoc ~DocumentManager(); - Document *addDocument (const std::string& name); + Document *addDocument (const std::vector& files, 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 + /// appropriate way. bool removeDocument (Document *document); ///< \return last document removed? From ba0d13fc12f2be6b483a09025b329f97974ae9b4 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Mon, 4 Feb 2013 13:50:38 +0100 Subject: [PATCH 07/18] moved code for creating new base content records into the Document class --- apps/opencs/editor.cpp | 19 +------------------ apps/opencs/model/doc/document.cpp | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 20 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 57e31e19ea..7156db94e7 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -22,7 +22,6 @@ void CS::Editor::createDocument() mStartup.hide(); /// \todo open the ESX picker instead - /// \todo move the following code for creating initial records into the document manager std::ostringstream stream; @@ -33,22 +32,6 @@ void CS::Editor::createDocument() CSMDoc::Document *document = mDocumentManager.addDocument (files, true); - static const char *sGlobals[] = - { - "Day", "DaysPassed", "GameHour", "Month", "PCRace", "PCVampire", "PCWerewolf", "PCYear", 0 - }; - - for (int i=0; sGlobals[i]; ++i) - { - ESM::Global record; - record.mId = sGlobals[i]; - record.mValue = i==0 ? 1 : 0; - record.mType = ESM::VT_Float; - document->getData().getGlobals().add (record); - } - - document->getData().merge(); /// \todo remove once proper ESX loading is implemented - mViewManager.addView (document); } @@ -57,7 +40,7 @@ void CS::Editor::loadDocument() mStartup.hide(); /// \todo open the ESX picker instead - /// \todo replace the manual record creation and load the ESX files instead + /// \todo remove the manual record creation and load the ESX files instead std::ostringstream stream; diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 93d664314e..14e34d0baf 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -14,9 +14,19 @@ void CSMDoc::Document::load (const std::vector::const_i void CSMDoc::Document::createBase() { - std::cout << "pretending to create base file records" << std::endl; + static const char *sGlobals[] = + { + "Day", "DaysPassed", "GameHour", "Month", "PCRace", "PCVampire", "PCWerewolf", "PCYear", 0 + }; - /// \todo create mandatory records for base content file + for (int i=0; sGlobals[i]; ++i) + { + ESM::Global record; + record.mId = sGlobals[i]; + record.mValue = i==0 ? 1 : 0; + record.mType = ESM::VT_Float; + getData().getGlobals().add (record); + } } CSMDoc::Document::Document (const std::vector& files, bool new_) From 66ec4ca7d9e8cd9abaea4dbee0a3b345ae66cabb Mon Sep 17 00:00:00 2001 From: Michal Sciubidlo Date: Mon, 4 Feb 2013 22:14:14 +0100 Subject: [PATCH 08/18] Split launcher specific code from DataFilesList back to DataFilesPage. --- apps/launcher/CMakeLists.txt | 9 + apps/launcher/datafilespage.cpp | 533 +++++++++++++++++ apps/launcher/datafilespage.hpp | 80 +++ apps/launcher/maindialog.cpp | 21 +- apps/launcher/maindialog.hpp | 4 +- .../launcher}/utils/profilescombobox.cpp | 0 .../launcher}/utils/profilescombobox.hpp | 0 .../launcher}/utils/textinputdialog.cpp | 0 .../launcher}/utils/textinputdialog.hpp | 0 apps/opencs/view/doc/opendialog.cpp | 39 +- components/CMakeLists.txt | 2 +- components/fileorderlist/datafileslist.cpp | 563 +----------------- components/fileorderlist/datafileslist.hpp | 31 +- 13 files changed, 706 insertions(+), 576 deletions(-) create mode 100644 apps/launcher/datafilespage.cpp create mode 100644 apps/launcher/datafilespage.hpp rename {components/fileorderlist => apps/launcher}/utils/profilescombobox.cpp (100%) rename {components/fileorderlist => apps/launcher}/utils/profilescombobox.hpp (100%) rename {components/fileorderlist => apps/launcher}/utils/textinputdialog.cpp (100%) rename {components/fileorderlist => apps/launcher}/utils/textinputdialog.hpp (100%) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index 73efb9ee51..ce0649cd64 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -3,6 +3,9 @@ set(LAUNCHER main.cpp maindialog.cpp playpage.cpp + datafilespage.cpp + utils/profilescombobox.cpp + utils/textinputdialog.cpp launcher.rc ) @@ -11,6 +14,9 @@ set(LAUNCHER_HEADER graphicspage.hpp maindialog.hpp playpage.hpp + datafilespage.hpp + utils/profilescombobox.hpp + utils/textinputdialog.hpp ) # Headers that must be pre-processed @@ -18,6 +24,9 @@ set(LAUNCHER_HEADER_MOC graphicspage.hpp maindialog.hpp playpage.hpp + datafilespage.hpp + utils/profilescombobox.hpp + utils/textinputdialog.hpp ) source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER} ${LAUNCHER_HEADER_MOC}) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp new file mode 100644 index 0000000000..52b8c9cbeb --- /dev/null +++ b/apps/launcher/datafilespage.cpp @@ -0,0 +1,533 @@ +#include + +#include +#include +#include +#include +#include +#include + +////#include "model/datafilesmodel.hpp" +////#include "model/esm/esmfile.hpp" + +#include "utils/profilescombobox.hpp" +////#include "utils/filedialog.hpp" +////#include "utils/naturalsort.hpp" +#include "utils/textinputdialog.hpp" + +#include "datafilespage.hpp" + +#include +/** + * Workaround for problems with whitespaces in paths in older versions of Boost library + */ +#if (BOOST_VERSION <= 104600) +namespace boost +{ + + template<> + inline boost::filesystem::path lexical_cast(const std::string& arg) + { + return boost::filesystem::path(arg); + } + +} /* namespace boost */ +#endif /* (BOOST_VERSION <= 104600) */ + +using namespace ESM; +using namespace std; + +DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, QWidget *parent) + : QWidget(parent) + , mCfgMgr(cfg) +{ + mDataFilesList = new DataFilesList(mCfgMgr, this); + + // Bottom part with profile options + QLabel *profileLabel = new QLabel(tr("Current Profile: "), this); + + mProfilesComboBox = new ProfilesComboBox(this); + mProfilesComboBox->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); + mProfilesComboBox->setInsertPolicy(QComboBox::NoInsert); + mProfilesComboBox->setDuplicatesEnabled(false); + mProfilesComboBox->setEditEnabled(false); + + mProfileToolBar = new QToolBar(this); + mProfileToolBar->setMovable(false); + mProfileToolBar->setIconSize(QSize(16, 16)); + + mProfileToolBar->addWidget(profileLabel); + mProfileToolBar->addWidget(mProfilesComboBox); + + QVBoxLayout *pageLayout = new QVBoxLayout(this); + + pageLayout->addWidget(mDataFilesList); + pageLayout->addWidget(mProfileToolBar); + + // Create a dialog for the new profile name input + mNewProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this); + + connect(mNewProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(updateOkButton(QString))); + + connect(mProfilesComboBox, SIGNAL(profileRenamed(QString,QString)), this, SLOT(profileRenamed(QString,QString))); + connect(mProfilesComboBox, SIGNAL(profileChanged(QString,QString)), this, SLOT(profileChanged(QString,QString))); + + createActions(); + setupConfig(); +} + +void DataFilesPage::createActions() +{ + // Refresh the plugins + QAction *refreshAction = new QAction(tr("Refresh"), this); + refreshAction->setShortcut(QKeySequence(tr("F5"))); + connect(refreshAction, SIGNAL(triggered()), this, SLOT(refresh())); + + // Profile actions + mNewProfileAction = new QAction(QIcon::fromTheme("document-new"), tr("&New Profile"), this); + mNewProfileAction->setToolTip(tr("New Profile")); + mNewProfileAction->setShortcut(QKeySequence(tr("Ctrl+N"))); + connect(mNewProfileAction, SIGNAL(triggered()), this, SLOT(newProfile())); + + mDeleteProfileAction = new QAction(QIcon::fromTheme("edit-delete"), tr("Delete Profile"), this); + mDeleteProfileAction->setToolTip(tr("Delete Profile")); + mDeleteProfileAction->setShortcut(QKeySequence(tr("Delete"))); + connect(mDeleteProfileAction, SIGNAL(triggered()), this, SLOT(deleteProfile())); + + // Add the newly created actions to the toolbar + mProfileToolBar->addSeparator(); + mProfileToolBar->addAction(mNewProfileAction); + mProfileToolBar->addAction(mDeleteProfileAction); +} + +void DataFilesPage::setupConfig() +{ + // Open our config file + QString config = QString::fromStdString((mCfgMgr.getUserPath() / "launcher.cfg").string()); + mLauncherConfig = new QSettings(config, QSettings::IniFormat); + + // Make sure we have no groups open + while (!mLauncherConfig->group().isEmpty()) { + mLauncherConfig->endGroup(); + } + + mLauncherConfig->beginGroup("Profiles"); + QStringList profiles = mLauncherConfig->childGroups(); + + // Add the profiles to the combobox + foreach (const QString &profile, profiles) { + + if (profile.contains(QRegExp("[^a-zA-Z0-9_]"))) + continue; // Profile name contains garbage + + + qDebug() << "adding " << profile; + mProfilesComboBox->addItem(profile); + } + + // Add a default profile + if (mProfilesComboBox->findText(QString("Default")) == -1) { + mProfilesComboBox->addItem(QString("Default")); + } + + QString currentProfile = mLauncherConfig->value("CurrentProfile").toString(); + + if (currentProfile.isEmpty()) { + // No current profile selected + currentProfile = "Default"; + } + + const int currentIndex = mProfilesComboBox->findText(currentProfile); + if (currentIndex != -1) { + // Profile is found + mProfilesComboBox->setCurrentIndex(currentIndex); + } + + mLauncherConfig->endGroup(); +} + + +void DataFilesPage::readConfig() +{ + QString profile = mProfilesComboBox->currentText(); + + // Make sure we have no groups open + while (!mLauncherConfig->group().isEmpty()) { + mLauncherConfig->endGroup(); + } + + mLauncherConfig->beginGroup("Profiles"); + mLauncherConfig->beginGroup(profile); + + QStringList childKeys = mLauncherConfig->childKeys(); + QStringList plugins; + + // Sort the child keys numerical instead of alphabetically + // i.e. Plugin1, Plugin2 instead of Plugin1, Plugin10 + qSort(childKeys.begin(), childKeys.end(), naturalSortLessThanCI); + + foreach (const QString &key, childKeys) { + const QString keyValue = mLauncherConfig->value(key).toString(); + + mDataFilesList->setCheckState(keyValue, Qt::Checked); + } + + qDebug() << plugins; +} + +bool DataFilesPage::showDataFilesWarning() +{ + + QMessageBox msgBox; + msgBox.setWindowTitle("Error detecting Morrowind installation"); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setStandardButtons(QMessageBox::Cancel); + msgBox.setText(tr("
Could not find the Data Files location

\ + The directory containing the data files was not found.

\ + Press \"Browse...\" to specify the location manually.
")); + + QAbstractButton *dirSelectButton = + msgBox.addButton(tr("B&rowse..."), QMessageBox::ActionRole); + + msgBox.exec(); + + if (msgBox.clickedButton() == dirSelectButton) { + + // Show a custom dir selection dialog which only accepts valid dirs + QString selectedDir = FileDialog::getExistingDirectory( + this, tr("Select Data Files Directory"), + QDir::currentPath(), + QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); + + // Add the user selected data directory + if (!selectedDir.isEmpty()) { + mDataDirs.push_back(Files::PathContainer::value_type(selectedDir.toStdString())); + mCfgMgr.processPaths(mDataDirs); + } else { + // Cancel from within the dir selection dialog + return false; + } + + } else { + // Cancel + return false; + } + + return true; +} + +bool DataFilesPage::setupDataFiles() +{ + // We use the Configuration Manager to retrieve the configuration values + boost::program_options::variables_map variables; + boost::program_options::options_description desc; + + desc.add_options() + ("data", boost::program_options::value()->default_value(Files::PathContainer(), "data")->multitoken()) + ("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")); + + boost::program_options::notify(variables); + + mCfgMgr.readConfiguration(variables, desc); + + if (variables["data"].empty()) { + if (!showDataFilesWarning()) + return false; + } else { + mDataDirs = Files::PathContainer(variables["data"].as()); + } + + std::string local = variables["data-local"].as(); + if (!local.empty()) { + mDataLocal.push_back(Files::PathContainer::value_type(local)); + } + + mCfgMgr.processPaths(mDataDirs); + mCfgMgr.processPaths(mDataLocal); + + // Second chance to display the warning, the data= entries are invalid + while (mDataDirs.empty()) { + if (!showDataFilesWarning()) + return false; + } + + // Set the charset for reading the esm/esp files + QString encoding = QString::fromStdString(variables["encoding"].as()); + + Files::PathContainer paths; + paths.insert(paths.end(), mDataDirs.begin(), mDataDirs.end()); + paths.insert(paths.end(), mDataLocal.begin(), mDataLocal.end()); + mDataFilesList->setupDataFiles(paths, encoding); + readConfig(); + return true; +} + +void DataFilesPage::writeConfig(QString profile) +{ + QString pathStr = QString::fromStdString(mCfgMgr.getUserPath().string()); + QDir userPath(pathStr); + + if (!userPath.exists()) { + if (!userPath.mkpath(pathStr)) { + QMessageBox msgBox; + msgBox.setWindowTitle("Error creating OpenMW configuration directory"); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(tr("
Could not create %0

\ + Please make sure you have the right permissions and try again.
").arg(pathStr)); + msgBox.exec(); + + qApp->quit(); + return; + } + } + // Open the OpenMW config as a QFile + QFile file(pathStr.append("openmw.cfg")); + + if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) { + // File cannot be opened or created + QMessageBox msgBox; + msgBox.setWindowTitle("Error writing OpenMW configuration file"); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(tr("
Could not open or create %0

\ + Please make sure you have the right permissions and try again.
").arg(file.fileName())); + msgBox.exec(); + + qApp->quit(); + return; + } + + QTextStream in(&file); + QByteArray buffer; + + // Remove all previous entries from config + while (!in.atEnd()) { + QString line = in.readLine(); + if (!line.startsWith("master") && + !line.startsWith("plugin") && + !line.startsWith("data") && + !line.startsWith("data-local")) + { + buffer += line += "\n"; + } + } + + file.close(); + + // Now we write back the other config entries + if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) { + QMessageBox msgBox; + msgBox.setWindowTitle("Error writing OpenMW configuration file"); + msgBox.setIcon(QMessageBox::Critical); + msgBox.setStandardButtons(QMessageBox::Ok); + msgBox.setText(tr("
Could not write to %0

\ + Please make sure you have the right permissions and try again.
").arg(file.fileName())); + msgBox.exec(); + + qApp->quit(); + return; + } + + if (!buffer.isEmpty()) { + file.write(buffer); + } + + QTextStream gameConfig(&file); + + // First write the list of data dirs + mCfgMgr.processPaths(mDataDirs); + mCfgMgr.processPaths(mDataLocal); + + QString path; + + // data= directories + for (Files::PathContainer::iterator it = mDataDirs.begin(); it != mDataDirs.end(); ++it) { + path = QString::fromStdString(it->string()); + path.remove(QChar('\"')); + + // Make sure the string is quoted when it contains spaces + if (path.contains(" ")) { + gameConfig << "data=\"" << path << "\"" << endl; + } else { + gameConfig << "data=" << path << endl; + } + } + + // data-local directory + if (!mDataLocal.empty()) { + path = QString::fromStdString(mDataLocal.front().string()); + path.remove(QChar('\"')); + + if (path.contains(" ")) { + gameConfig << "data-local=\"" << path << "\"" << endl; + } else { + gameConfig << "data-local=" << path << endl; + } + } + + + if (profile.isEmpty()) + profile = mProfilesComboBox->currentText(); + + if (profile.isEmpty()) + return; + + // Make sure we have no groups open + while (!mLauncherConfig->group().isEmpty()) { + mLauncherConfig->endGroup(); + } + + mLauncherConfig->beginGroup("Profiles"); + mLauncherConfig->setValue("CurrentProfile", profile); + + // Open the profile-name subgroup + mLauncherConfig->beginGroup(profile); + mLauncherConfig->remove(""); // Clear the subgroup + + // Now write the masters to the configs + const QStringList checkedFiles = mDataFilesList->checkedFiles(); + for(int i=0; i < checkedFiles.size(); i++) + { + if (checkedFiles.at(i).lastIndexOf("esm") != -1) + { + mLauncherConfig->setValue(QString("Master%0").arg(i), checkedFiles.at(i)); + gameConfig << "master=" << checkedFiles.at(i) << endl; + } + else + { + mLauncherConfig->setValue(QString("Plugin%1").arg(i), checkedFiles.at(i)); + gameConfig << "plugin=" << checkedFiles.at(i) << endl; + } + } + + file.close(); + mLauncherConfig->endGroup(); + mLauncherConfig->endGroup(); + mLauncherConfig->sync(); +} + + +void DataFilesPage::newProfile() +{ + if (mNewProfileDialog->exec() == QDialog::Accepted) { + + const QString text = mNewProfileDialog->lineEdit()->text(); + mProfilesComboBox->addItem(text); + + // Copy the currently checked items to cfg + writeConfig(text); + mLauncherConfig->sync(); + + mProfilesComboBox->setCurrentIndex(mProfilesComboBox->findText(text)); + } +} + +void DataFilesPage::updateOkButton(const QString &text) +{ + if (text.isEmpty()) { + mNewProfileDialog->setOkButtonEnabled(false); + return; + } + + (mProfilesComboBox->findText(text) == -1) + ? mNewProfileDialog->setOkButtonEnabled(true) + : mNewProfileDialog->setOkButtonEnabled(false); +} + +void DataFilesPage::deleteProfile() +{ + QString profile = mProfilesComboBox->currentText(); + + if (profile.isEmpty()) + return; + + QMessageBox msgBox(this); + msgBox.setWindowTitle(tr("Delete Profile")); + msgBox.setIcon(QMessageBox::Warning); + msgBox.setStandardButtons(QMessageBox::Cancel); + msgBox.setText(tr("Are you sure you want to delete %0?").arg(profile)); + + QAbstractButton *deleteButton = + msgBox.addButton(tr("Delete"), QMessageBox::ActionRole); + + msgBox.exec(); + + if (msgBox.clickedButton() == deleteButton) { + // Make sure we have no groups open + while (!mLauncherConfig->group().isEmpty()) { + mLauncherConfig->endGroup(); + } + + mLauncherConfig->beginGroup("Profiles"); + + // Open the profile-name subgroup + mLauncherConfig->beginGroup(profile); + mLauncherConfig->remove(""); // Clear the subgroup + mLauncherConfig->endGroup(); + mLauncherConfig->endGroup(); + + // Remove the profile from the combobox + mProfilesComboBox->removeItem(mProfilesComboBox->findText(profile)); + } +} + +void DataFilesPage::profileChanged(const QString &previous, const QString ¤t) +{ + qDebug() << "Profile is changed from: " << previous << " to " << current; + // Prevent the deletion of the default profile + if (current == QLatin1String("Default")) { + mDeleteProfileAction->setEnabled(false); + mProfilesComboBox->setEditEnabled(false); + } else { + mDeleteProfileAction->setEnabled(true); + mProfilesComboBox->setEditEnabled(true); + } + + if (!previous.isEmpty()) { + writeConfig(previous); + mLauncherConfig->sync(); + + if (mProfilesComboBox->currentIndex() == -1) + return; + + } else { + return; + } + + mDataFilesList->uncheckAll(); + readConfig(); +} + +void DataFilesPage::profileRenamed(const QString &previous, const QString ¤t) +{ + if (previous.isEmpty()) + return; + + // Save the new profile name + writeConfig(current); + + // Make sure we have no groups open + while (!mLauncherConfig->group().isEmpty()) { + mLauncherConfig->endGroup(); + } + + mLauncherConfig->beginGroup("Profiles"); + + // Open the profile-name subgroup + mLauncherConfig->beginGroup(previous); + mLauncherConfig->remove(""); // Clear the subgroup + mLauncherConfig->endGroup(); + mLauncherConfig->endGroup(); + mLauncherConfig->sync(); + + // Remove the profile from the combobox + mProfilesComboBox->removeItem(mProfilesComboBox->findText(previous)); + + mDataFilesList->uncheckAll(); + ////mMastersModel->uncheckAll(); + ////mPluginsModel->uncheckAll(); + readConfig(); +} diff --git a/apps/launcher/datafilespage.hpp b/apps/launcher/datafilespage.hpp new file mode 100644 index 0000000000..0584de4364 --- /dev/null +++ b/apps/launcher/datafilespage.hpp @@ -0,0 +1,80 @@ +#ifndef DATAFILESPAGE_H +#define DATAFILESPAGE_H + +#include +#include +#include "utils/profilescombobox.hpp" +#include + + +class QTableView; +class QSortFilterProxyModel; +class QSettings; +class QAction; +class QToolBar; +class QMenu; +class ProfilesComboBox; +class DataFilesModel; + +class TextInputDialog; +class DataFilesList; + +namespace Files { struct ConfigurationManager; } + +class DataFilesPage : public QWidget +{ + Q_OBJECT + +public: + DataFilesPage(Files::ConfigurationManager& cfg, QWidget *parent = 0); + + ProfilesComboBox *mProfilesComboBox; + + void writeConfig(QString profile = QString()); + bool showDataFilesWarning(); + bool setupDataFiles(); + +public slots: + void profileChanged(const QString &previous, const QString ¤t); + void profileRenamed(const QString &previous, const QString ¤t); + void updateOkButton(const QString &text); + + // Action slots + void newProfile(); + void deleteProfile(); +// void moveUp(); +// void moveDown(); +// void moveTop(); +// void moveBottom(); + +private: + DataFilesList *mDataFilesList; + + QToolBar *mProfileToolBar; + + QAction *mNewProfileAction; + QAction *mDeleteProfileAction; + +// QAction *mMoveUpAction; +// QAction *mMoveDownAction; +// QAction *mMoveTopAction; +// QAction *mMoveBottomAction; + + Files::ConfigurationManager &mCfgMgr; + Files::PathContainer mDataDirs; + Files::PathContainer mDataLocal; + + QSettings *mLauncherConfig; + + TextInputDialog *mNewProfileDialog; + +// const QStringList checkedPlugins(); +// const QStringList selectedMasters(); + + void createActions(); + void setupConfig(); + void readConfig(); + +}; + +#endif diff --git a/apps/launcher/maindialog.cpp b/apps/launcher/maindialog.cpp index 7914650fe9..674ccdf672 100644 --- a/apps/launcher/maindialog.cpp +++ b/apps/launcher/maindialog.cpp @@ -1,10 +1,9 @@ #include -#include - #include "maindialog.hpp" #include "playpage.hpp" #include "graphicspage.hpp" +#include "datafilespage.hpp" MainDialog::MainDialog() { @@ -124,16 +123,16 @@ void MainDialog::createPages() { mPlayPage = new PlayPage(this); mGraphicsPage = new GraphicsPage(mCfgMgr, this); - mDataFilesList = new DataFilesList(mCfgMgr, this); + mDataFilesPage = new DataFilesPage(mCfgMgr, this); // Set the combobox of the play page to imitate the combobox on the datafilespage - mPlayPage->mProfilesComboBox->setModel(mDataFilesList->mProfilesComboBox->model()); - mPlayPage->mProfilesComboBox->setCurrentIndex(mDataFilesList->mProfilesComboBox->currentIndex()); + mPlayPage->mProfilesComboBox->setModel(mDataFilesPage->mProfilesComboBox->model()); + mPlayPage->mProfilesComboBox->setCurrentIndex(mDataFilesPage->mProfilesComboBox->currentIndex()); // Add the pages to the stacked widget mPagesWidget->addWidget(mPlayPage); mPagesWidget->addWidget(mGraphicsPage); - mPagesWidget->addWidget(mDataFilesList); + mPagesWidget->addWidget(mDataFilesPage); // Select the first page mIconWidget->setCurrentItem(mIconWidget->item(0), QItemSelectionModel::Select); @@ -142,9 +141,9 @@ void MainDialog::createPages() connect(mPlayPage->mProfilesComboBox, SIGNAL(currentIndexChanged(int)), - mDataFilesList->mProfilesComboBox, SLOT(setCurrentIndex(int))); + mDataFilesPage->mProfilesComboBox, SLOT(setCurrentIndex(int))); - connect(mDataFilesList->mProfilesComboBox, + connect(mDataFilesPage->mProfilesComboBox, SIGNAL(currentIndexChanged(int)), mPlayPage->mProfilesComboBox, SLOT(setCurrentIndex(int))); @@ -190,7 +189,7 @@ bool MainDialog::setup() } // Setup the Data Files page - if (!mDataFilesList->setupDataFiles()) { + if (!mDataFilesPage->setupDataFiles()) { return false; } @@ -208,7 +207,7 @@ void MainDialog::changePage(QListWidgetItem *current, QListWidgetItem *previous) void MainDialog::closeEvent(QCloseEvent *event) { // Now write all config files - mDataFilesList->writeConfig(); + mDataFilesPage->writeConfig(); mGraphicsPage->writeConfig(); // Save user settings @@ -221,7 +220,7 @@ void MainDialog::closeEvent(QCloseEvent *event) void MainDialog::play() { // First do a write of all the configs, just to be sure - mDataFilesList->writeConfig(); + mDataFilesPage->writeConfig(); mGraphicsPage->writeConfig(); // Save user settings diff --git a/apps/launcher/maindialog.hpp b/apps/launcher/maindialog.hpp index 5a39c11a99..bf98011cc4 100644 --- a/apps/launcher/maindialog.hpp +++ b/apps/launcher/maindialog.hpp @@ -15,7 +15,7 @@ class QString; class PlayPage; class GraphicsPage; -class DataFilesList; +class DataFilesPage; class MainDialog : public QMainWindow { @@ -39,7 +39,7 @@ private: PlayPage *mPlayPage; GraphicsPage *mGraphicsPage; - DataFilesList *mDataFilesList; + DataFilesPage *mDataFilesPage; Files::ConfigurationManager mCfgMgr; Settings::Manager mSettings; diff --git a/components/fileorderlist/utils/profilescombobox.cpp b/apps/launcher/utils/profilescombobox.cpp similarity index 100% rename from components/fileorderlist/utils/profilescombobox.cpp rename to apps/launcher/utils/profilescombobox.cpp diff --git a/components/fileorderlist/utils/profilescombobox.hpp b/apps/launcher/utils/profilescombobox.hpp similarity index 100% rename from components/fileorderlist/utils/profilescombobox.hpp rename to apps/launcher/utils/profilescombobox.hpp diff --git a/components/fileorderlist/utils/textinputdialog.cpp b/apps/launcher/utils/textinputdialog.cpp similarity index 100% rename from components/fileorderlist/utils/textinputdialog.cpp rename to apps/launcher/utils/textinputdialog.cpp diff --git a/components/fileorderlist/utils/textinputdialog.hpp b/apps/launcher/utils/textinputdialog.hpp similarity index 100% rename from components/fileorderlist/utils/textinputdialog.hpp rename to apps/launcher/utils/textinputdialog.hpp diff --git a/apps/opencs/view/doc/opendialog.cpp b/apps/opencs/view/doc/opendialog.cpp index f51cbadb97..9a5feb23a7 100644 --- a/apps/opencs/view/doc/opendialog.cpp +++ b/apps/opencs/view/doc/opendialog.cpp @@ -10,7 +10,42 @@ OpenDialog::OpenDialog(QWidget * parent) : QDialog(parent) QVBoxLayout *layout = new QVBoxLayout(this); mFileSelector = new DataFilesList(mCfgMgr, this); layout->addWidget(mFileSelector); - mFileSelector->setupDataFiles(); + + //FIXME - same as DataFilesPage::setupDataFiles + // We use the Configuration Manager to retrieve the configuration values + boost::program_options::variables_map variables; + boost::program_options::options_description desc; + + desc.add_options() + ("data", boost::program_options::value()->default_value(Files::PathContainer(), "data")->multitoken()) + ("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")); + + boost::program_options::notify(variables); + + mCfgMgr.readConfiguration(variables, desc); + + Files::PathContainer mDataDirs, mDataLocal; + if (!variables["data"].empty()) { + mDataDirs = Files::PathContainer(variables["data"].as()); + } + + std::string local = variables["data-local"].as(); + if (!local.empty()) { + mDataLocal.push_back(Files::PathContainer::value_type(local)); + } + + mCfgMgr.processPaths(mDataDirs); + mCfgMgr.processPaths(mDataLocal); + + // Set the charset for reading the esm/esp files + QString encoding = QString::fromStdString(variables["encoding"].as()); + + Files::PathContainer dataDirs; + dataDirs.insert(dataDirs.end(), mDataDirs.begin(), mDataDirs.end()); + dataDirs.insert(dataDirs.end(), mDataLocal.begin(), mDataLocal.end()); + mFileSelector->setupDataFiles(dataDirs, encoding); buttonBox = new QDialogButtonBox(QDialogButtonBox::Open | QDialogButtonBox::Cancel, Qt::Horizontal, this); connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept())); @@ -23,5 +58,5 @@ OpenDialog::OpenDialog(QWidget * parent) : QDialog(parent) void OpenDialog::getFileList(std::vector& paths) { - mFileSelector->getSelectedFiles(paths); + mFileSelector->selectedFiles(paths); } diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 63a2276217..00342e2ac8 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -71,7 +71,7 @@ find_package(Qt4 COMPONENTS QtCore QtGui) if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY) add_component_qt_dir (fileorderlist datafileslist model/modelitem model/datafilesmodel model/esm/esmfile - utils/filedialog utils/lineedit utils/profilescombobox utils/textinputdialog utils/naturalsort + utils/filedialog utils/lineedit utils/naturalsort ) include(${QT_USE_FILE}) diff --git a/components/fileorderlist/datafileslist.cpp b/components/fileorderlist/datafileslist.cpp index f346407a90..38e0bfb1a5 100644 --- a/components/fileorderlist/datafileslist.cpp +++ b/components/fileorderlist/datafileslist.cpp @@ -6,11 +6,9 @@ #include "model/datafilesmodel.hpp" #include "model/esm/esmfile.hpp" -#include "utils/profilescombobox.hpp" #include "utils/filedialog.hpp" #include "utils/lineedit.hpp" #include "utils/naturalsort.hpp" -#include "utils/textinputdialog.hpp" #include "datafileslist.hpp" @@ -137,32 +135,10 @@ DataFilesList::DataFilesList(Files::ConfigurationManager &cfg, QWidget *parent) sizeList << 175 << 200; splitter->setSizes(sizeList); - // Bottom part with profile options - QLabel *profileLabel = new QLabel(tr("Current Profile: "), this); - - mProfilesComboBox = new ProfilesComboBox(this); - mProfilesComboBox->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); - mProfilesComboBox->setInsertPolicy(QComboBox::NoInsert); - mProfilesComboBox->setDuplicatesEnabled(false); - mProfilesComboBox->setEditEnabled(false); - - mProfileToolBar = new QToolBar(this); - mProfileToolBar->setMovable(false); - mProfileToolBar->setIconSize(QSize(16, 16)); - - mProfileToolBar->addWidget(profileLabel); - mProfileToolBar->addWidget(mProfilesComboBox); - QVBoxLayout *pageLayout = new QVBoxLayout(this); pageLayout->addWidget(filterToolBar); pageLayout->addWidget(splitter); - pageLayout->addWidget(mProfileToolBar); - - // Create a dialog for the new profile name input - mNewProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this); - - connect(mNewProfileDialog->lineEdit(), SIGNAL(textChanged(QString)), this, SLOT(updateOkButton(QString))); connect(mPluginsTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); connect(mMastersTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); @@ -173,11 +149,7 @@ DataFilesList::DataFilesList(Files::ConfigurationManager &cfg, QWidget *parent) connect(mPluginsTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); - connect(mProfilesComboBox, SIGNAL(profileRenamed(QString,QString)), this, SLOT(profileRenamed(QString,QString))); - connect(mProfilesComboBox, SIGNAL(profileChanged(QString,QString)), this, SLOT(profileChanged(QString,QString))); - createActions(); - setupConfig(); } void DataFilesList::createActions() @@ -187,22 +159,6 @@ void DataFilesList::createActions() refreshAction->setShortcut(QKeySequence(tr("F5"))); connect(refreshAction, SIGNAL(triggered()), this, SLOT(refresh())); - // Profile actions - mNewProfileAction = new QAction(QIcon::fromTheme("document-new"), tr("&New Profile"), this); - mNewProfileAction->setToolTip(tr("New Profile")); - mNewProfileAction->setShortcut(QKeySequence(tr("Ctrl+N"))); - connect(mNewProfileAction, SIGNAL(triggered()), this, SLOT(newProfile())); - - mDeleteProfileAction = new QAction(QIcon::fromTheme("edit-delete"), tr("Delete Profile"), this); - mDeleteProfileAction->setToolTip(tr("Delete Profile")); - mDeleteProfileAction->setShortcut(QKeySequence(tr("Delete"))); - connect(mDeleteProfileAction, SIGNAL(triggered()), this, SLOT(deleteProfile())); - - // Add the newly created actions to the toolbar - mProfileToolBar->addSeparator(); - mProfileToolBar->addAction(mNewProfileAction); - mProfileToolBar->addAction(mDeleteProfileAction); - // Context menu actions mCheckAction = new QAction(tr("Check selected"), this); connect(mCheckAction, SIGNAL(triggered()), this, SLOT(check())); @@ -218,223 +174,16 @@ void DataFilesList::createActions() } -void DataFilesList::setupConfig() +bool DataFilesList::setupDataFiles(Files::PathContainer dataDirs, const QString encoding) { - // Open our config file - QString config = QString::fromStdString((mCfgMgr.getUserPath() / "launcher.cfg").string()); - mLauncherConfig = new QSettings(config, QSettings::IniFormat); - - // Make sure we have no groups open - while (!mLauncherConfig->group().isEmpty()) { - mLauncherConfig->endGroup(); - } - - mLauncherConfig->beginGroup("Profiles"); - QStringList profiles = mLauncherConfig->childGroups(); - - // Add the profiles to the combobox - foreach (const QString &profile, profiles) { - - if (profile.contains(QRegExp("[^a-zA-Z0-9_]"))) - continue; // Profile name contains garbage - - - qDebug() << "adding " << profile; - mProfilesComboBox->addItem(profile); - } - - // Add a default profile - if (mProfilesComboBox->findText(QString("Default")) == -1) { - mProfilesComboBox->addItem(QString("Default")); - } - - QString currentProfile = mLauncherConfig->value("CurrentProfile").toString(); - - if (currentProfile.isEmpty()) { - // No current profile selected - currentProfile = "Default"; - } - - const int currentIndex = mProfilesComboBox->findText(currentProfile); - if (currentIndex != -1) { - // Profile is found - mProfilesComboBox->setCurrentIndex(currentIndex); - } - - mLauncherConfig->endGroup(); -} - - -void DataFilesList::readConfig() -{ - // Don't read the config if no masters are found - if (mMastersModel->rowCount() < 1) - return; - - QString profile = mProfilesComboBox->currentText(); - - // Make sure we have no groups open - while (!mLauncherConfig->group().isEmpty()) { - mLauncherConfig->endGroup(); - } - - mLauncherConfig->beginGroup("Profiles"); - mLauncherConfig->beginGroup(profile); - - QStringList childKeys = mLauncherConfig->childKeys(); - QStringList plugins; - - // Sort the child keys numerical instead of alphabetically - // i.e. Plugin1, Plugin2 instead of Plugin1, Plugin10 - qSort(childKeys.begin(), childKeys.end(), naturalSortLessThanCI); - - foreach (const QString &key, childKeys) { - const QString keyValue = mLauncherConfig->value(key).toString(); - - if (key.startsWith("Plugin")) { - //QStringList checked = mPluginsModel->checkedItems(); - EsmFile *file = mPluginsModel->findItem(keyValue); - QModelIndex index = mPluginsModel->indexFromItem(file); - - mPluginsModel->setCheckState(index, Qt::Checked); - // Move the row to the top of te view - //mPluginsModel->moveRow(index.row(), checked.count()); - plugins << keyValue; - } - - if (key.startsWith("Master")) { - EsmFile *file = mMastersModel->findItem(keyValue); - mMastersModel->setCheckState(mMastersModel->indexFromItem(file), Qt::Checked); - } - } - - qDebug() << plugins; - - -// // Set the checked item positions -// const QStringList checked = mPluginsModel->checkedItems(); -// for (int i = 0; i < plugins.size(); ++i) { -// EsmFile *file = mPluginsModel->findItem(plugins.at(i)); -// QModelIndex index = mPluginsModel->indexFromItem(file); -// mPluginsModel->moveRow(index.row(), i); -// qDebug() << "Moving: " << plugins.at(i) << " from: " << index.row() << " to: " << i << " count: " << checked.count(); - -// } - - // Iterate over the plugins to set their checkstate and position -// for (int i = 0; i < plugins.size(); ++i) { -// const QString plugin = plugins.at(i); - -// const QList pluginList = mPluginsModel->findItems(plugin); - -// if (!pluginList.isEmpty()) -// { -// foreach (const QStandardItem *currentPlugin, pluginList) { -// mPluginsModel->setData(currentPlugin->index(), Qt::Checked, Qt::CheckStateRole); - -// // Move the plugin to the position specified in the config file -// mPluginsModel->insertRow(i, mPluginsModel->takeRow(currentPlugin->row())); -// } -// } -// } - -} - -bool DataFilesList::showDataFilesWarning() -{ - - QMessageBox msgBox; - msgBox.setWindowTitle("Error detecting Morrowind installation"); - msgBox.setIcon(QMessageBox::Warning); - msgBox.setStandardButtons(QMessageBox::Cancel); - msgBox.setText(tr("
Could not find the Data Files location

\ - The directory containing the data files was not found.

\ - Press \"Browse...\" to specify the location manually.
")); - - QAbstractButton *dirSelectButton = - msgBox.addButton(tr("B&rowse..."), QMessageBox::ActionRole); - - msgBox.exec(); - - if (msgBox.clickedButton() == dirSelectButton) { - - // Show a custom dir selection dialog which only accepts valid dirs - QString selectedDir = FileDialog::getExistingDirectory( - this, tr("Select Data Files Directory"), - QDir::currentPath(), - QFileDialog::ShowDirsOnly | QFileDialog::DontResolveSymlinks); - - // Add the user selected data directory - if (!selectedDir.isEmpty()) { - mDataDirs.push_back(Files::PathContainer::value_type(selectedDir.toStdString())); - mCfgMgr.processPaths(mDataDirs); - } else { - // Cancel from within the dir selection dialog - return false; - } - - } else { - // Cancel - return false; - } - - return true; -} - -bool DataFilesList::setupDataFiles() -{ - // We use the Configuration Manager to retrieve the configuration values - boost::program_options::variables_map variables; - boost::program_options::options_description desc; - - desc.add_options() - ("data", boost::program_options::value()->default_value(Files::PathContainer(), "data")->multitoken()) - ("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")); - - boost::program_options::notify(variables); - - mCfgMgr.readConfiguration(variables, desc); - - if (variables["data"].empty()) { - if (!showDataFilesWarning()) - return false; - } else { - mDataDirs = Files::PathContainer(variables["data"].as()); - } - - std::string local = variables["data-local"].as(); - if (!local.empty()) { - mDataLocal.push_back(Files::PathContainer::value_type(local)); - } - - mCfgMgr.processPaths(mDataDirs); - mCfgMgr.processPaths(mDataLocal); - - // Second chance to display the warning, the data= entries are invalid - while (mDataDirs.empty()) { - if (!showDataFilesWarning()) - return false; - } - // Set the charset for reading the esm/esp files - QString encoding = QString::fromStdString(variables["encoding"].as()); if (!encoding.isEmpty() && encoding != QLatin1String("win1252")) { mMastersModel->setEncoding(encoding); mPluginsModel->setEncoding(encoding); } // Add the paths to the respective models - for (Files::PathContainer::iterator it = mDataDirs.begin(); it != mDataDirs.end(); ++it) { - QString path = QString::fromStdString(it->string()); - path.remove(QChar('\"')); - mMastersModel->addMasters(path); - mPluginsModel->addPlugins(path); - } - - // Same for the data-local paths - for (Files::PathContainer::iterator it = mDataLocal.begin(); it != mDataLocal.end(); ++it) { + for (Files::PathContainer::iterator it = dataDirs.begin(); it != dataDirs.end(); ++it) { QString path = QString::fromStdString(it->string()); path.remove(QChar('\"')); mMastersModel->addMasters(path); @@ -446,12 +195,10 @@ bool DataFilesList::setupDataFiles() // mMastersTable->sortByColumn(3, Qt::AscendingOrder); // mPluginsTable->sortByColumn(3, Qt::AscendingOrder); - - readConfig(); return true; } -void DataFilesList::getSelectedFiles(std::vector& paths) +void DataFilesList::selectedFiles(std::vector& paths) { QStringList masterPaths = mMastersModel->checkedItemsPaths(); foreach (const QString &path, masterPaths) @@ -467,225 +214,6 @@ void DataFilesList::getSelectedFiles(std::vector& paths } } -void DataFilesList::writeConfig(QString profile) -{ - // Don't overwrite the config if no masters are found - if (mMastersModel->rowCount() < 1) - return; - - QString pathStr = QString::fromStdString(mCfgMgr.getUserPath().string()); - QDir userPath(pathStr); - - if (!userPath.exists()) { - if (!userPath.mkpath(pathStr)) { - QMessageBox msgBox; - msgBox.setWindowTitle("Error creating OpenMW configuration directory"); - msgBox.setIcon(QMessageBox::Critical); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(tr("
Could not create %0

\ - Please make sure you have the right permissions and try again.
").arg(pathStr)); - msgBox.exec(); - - qApp->quit(); - return; - } - } - // Open the OpenMW config as a QFile - QFile file(pathStr.append("openmw.cfg")); - - if (!file.open(QIODevice::ReadWrite | QIODevice::Text)) { - // File cannot be opened or created - QMessageBox msgBox; - msgBox.setWindowTitle("Error writing OpenMW configuration file"); - msgBox.setIcon(QMessageBox::Critical); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(tr("
Could not open or create %0

\ - Please make sure you have the right permissions and try again.
").arg(file.fileName())); - msgBox.exec(); - - qApp->quit(); - return; - } - - QTextStream in(&file); - QByteArray buffer; - - // Remove all previous entries from config - while (!in.atEnd()) { - QString line = in.readLine(); - if (!line.startsWith("master") && - !line.startsWith("plugin") && - !line.startsWith("data") && - !line.startsWith("data-local")) - { - buffer += line += "\n"; - } - } - - file.close(); - - // Now we write back the other config entries - if (!file.open(QIODevice::WriteOnly | QIODevice::Text | QIODevice::Truncate)) { - QMessageBox msgBox; - msgBox.setWindowTitle("Error writing OpenMW configuration file"); - msgBox.setIcon(QMessageBox::Critical); - msgBox.setStandardButtons(QMessageBox::Ok); - msgBox.setText(tr("
Could not write to %0

\ - Please make sure you have the right permissions and try again.
").arg(file.fileName())); - msgBox.exec(); - - qApp->quit(); - return; - } - - if (!buffer.isEmpty()) { - file.write(buffer); - } - - QTextStream gameConfig(&file); - - // First write the list of data dirs - mCfgMgr.processPaths(mDataDirs); - mCfgMgr.processPaths(mDataLocal); - - QString path; - - // data= directories - for (Files::PathContainer::iterator it = mDataDirs.begin(); it != mDataDirs.end(); ++it) { - path = QString::fromStdString(it->string()); - path.remove(QChar('\"')); - - // Make sure the string is quoted when it contains spaces - if (path.contains(" ")) { - gameConfig << "data=\"" << path << "\"" << endl; - } else { - gameConfig << "data=" << path << endl; - } - } - - // data-local directory - if (!mDataLocal.empty()) { - path = QString::fromStdString(mDataLocal.front().string()); - path.remove(QChar('\"')); - - if (path.contains(" ")) { - gameConfig << "data-local=\"" << path << "\"" << endl; - } else { - gameConfig << "data-local=" << path << endl; - } - } - - - if (profile.isEmpty()) - profile = mProfilesComboBox->currentText(); - - if (profile.isEmpty()) - return; - - // Make sure we have no groups open - while (!mLauncherConfig->group().isEmpty()) { - mLauncherConfig->endGroup(); - } - - mLauncherConfig->beginGroup("Profiles"); - mLauncherConfig->setValue("CurrentProfile", profile); - - // Open the profile-name subgroup - mLauncherConfig->beginGroup(profile); - mLauncherConfig->remove(""); // Clear the subgroup - - // Now write the masters to the configs - const QStringList masters = mMastersModel->checkedItems(); - - // We don't use foreach because we need i - for (int i = 0; i < masters.size(); ++i) { - const QString currentMaster = masters.at(i); - - mLauncherConfig->setValue(QString("Master%0").arg(i), currentMaster); - gameConfig << "master=" << currentMaster << endl; - - } - - // And finally write all checked plugins - const QStringList plugins = mPluginsModel->checkedItems(); - - for (int i = 0; i < plugins.size(); ++i) { - const QString currentPlugin = plugins.at(i); - mLauncherConfig->setValue(QString("Plugin%1").arg(i), currentPlugin); - gameConfig << "plugin=" << currentPlugin << endl; - } - - file.close(); - mLauncherConfig->endGroup(); - mLauncherConfig->endGroup(); - mLauncherConfig->sync(); -} - - -void DataFilesList::newProfile() -{ - if (mNewProfileDialog->exec() == QDialog::Accepted) { - - const QString text = mNewProfileDialog->lineEdit()->text(); - mProfilesComboBox->addItem(text); - - // Copy the currently checked items to cfg - writeConfig(text); - mLauncherConfig->sync(); - - mProfilesComboBox->setCurrentIndex(mProfilesComboBox->findText(text)); - } -} - -void DataFilesList::updateOkButton(const QString &text) -{ - if (text.isEmpty()) { - mNewProfileDialog->setOkButtonEnabled(false); - return; - } - - (mProfilesComboBox->findText(text) == -1) - ? mNewProfileDialog->setOkButtonEnabled(true) - : mNewProfileDialog->setOkButtonEnabled(false); -} - -void DataFilesList::deleteProfile() -{ - QString profile = mProfilesComboBox->currentText(); - - if (profile.isEmpty()) - return; - - QMessageBox msgBox(this); - msgBox.setWindowTitle(tr("Delete Profile")); - msgBox.setIcon(QMessageBox::Warning); - msgBox.setStandardButtons(QMessageBox::Cancel); - msgBox.setText(tr("Are you sure you want to delete %0?").arg(profile)); - - QAbstractButton *deleteButton = - msgBox.addButton(tr("Delete"), QMessageBox::ActionRole); - - msgBox.exec(); - - if (msgBox.clickedButton() == deleteButton) { - // Make sure we have no groups open - while (!mLauncherConfig->group().isEmpty()) { - mLauncherConfig->endGroup(); - } - - mLauncherConfig->beginGroup("Profiles"); - - // Open the profile-name subgroup - mLauncherConfig->beginGroup(profile); - mLauncherConfig->remove(""); // Clear the subgroup - mLauncherConfig->endGroup(); - mLauncherConfig->endGroup(); - - // Remove the profile from the combobox - mProfilesComboBox->removeItem(mProfilesComboBox->findText(profile)); - } -} - void DataFilesList::check() { // Check the current selection @@ -733,8 +261,6 @@ void DataFilesList::refresh() // Refresh the plugins table mPluginsTable->scrollToTop(); - writeConfig(); - readConfig(); } @@ -767,70 +293,18 @@ void DataFilesList::setCheckState(QModelIndex index) } +void DataFilesList::uncheckAll() +{ + mMastersModel->uncheckAll(); + mPluginsModel->uncheckAll(); +} + void DataFilesList::filterChanged(const QString filter) { QRegExp regExp(filter, Qt::CaseInsensitive, QRegExp::FixedString); mPluginsProxyModel->setFilterRegExp(regExp); } -void DataFilesList::profileChanged(const QString &previous, const QString ¤t) -{ - qDebug() << "Profile is changed from: " << previous << " to " << current; - // Prevent the deletion of the default profile - if (current == QLatin1String("Default")) { - mDeleteProfileAction->setEnabled(false); - mProfilesComboBox->setEditEnabled(false); - } else { - mDeleteProfileAction->setEnabled(true); - mProfilesComboBox->setEditEnabled(true); - } - - if (!previous.isEmpty()) { - writeConfig(previous); - mLauncherConfig->sync(); - - if (mProfilesComboBox->currentIndex() == -1) - return; - - } else { - return; - } - - mMastersModel->uncheckAll(); - mPluginsModel->uncheckAll(); - readConfig(); -} - -void DataFilesList::profileRenamed(const QString &previous, const QString ¤t) -{ - if (previous.isEmpty()) - return; - - // Save the new profile name - writeConfig(current); - - // Make sure we have no groups open - while (!mLauncherConfig->group().isEmpty()) { - mLauncherConfig->endGroup(); - } - - mLauncherConfig->beginGroup("Profiles"); - - // Open the profile-name subgroup - mLauncherConfig->beginGroup(previous); - mLauncherConfig->remove(""); // Clear the subgroup - mLauncherConfig->endGroup(); - mLauncherConfig->endGroup(); - mLauncherConfig->sync(); - - // Remove the profile from the combobox - mProfilesComboBox->removeItem(mProfilesComboBox->findText(previous)); - - mMastersModel->uncheckAll(); - mPluginsModel->uncheckAll(); - readConfig(); -} - void DataFilesList::showContextMenu(const QPoint &point) { // Make sure there are plugins in the view @@ -858,3 +332,22 @@ void DataFilesList::showContextMenu(const QPoint &point) // Show menu mContextMenu->exec(globalPos); } + +void DataFilesList::setCheckState(const QString& element, Qt::CheckState state) +{ + EsmFile *file = mPluginsModel->findItem(element); + if (file) + { + mPluginsModel->setCheckState(mPluginsModel->indexFromItem(file), Qt::Checked); + } + else + { + file = mMastersModel->findItem(element); + mMastersModel->setCheckState(mMastersModel->indexFromItem(file), Qt::Checked); + } +} + +QStringList DataFilesList::checkedFiles() +{ + return mMastersModel->checkedItems() + mPluginsModel->checkedItems(); +} \ No newline at end of file diff --git a/components/fileorderlist/datafileslist.hpp b/components/fileorderlist/datafileslist.hpp index 7bdb5e0571..4b158d316d 100644 --- a/components/fileorderlist/datafileslist.hpp +++ b/components/fileorderlist/datafileslist.hpp @@ -3,7 +3,6 @@ #include #include -#include "utils/profilescombobox.hpp" #include @@ -27,25 +26,20 @@ class DataFilesList : public QWidget public: DataFilesList(Files::ConfigurationManager& cfg, QWidget *parent = 0); - ProfilesComboBox *mProfilesComboBox; - - void writeConfig(QString profile = QString()); - bool showDataFilesWarning(); - bool setupDataFiles(); - void getSelectedFiles(std::vector& paths); + bool setupDataFiles(Files::PathContainer dataDirs, const QString encoding); + void selectedFiles(std::vector& paths); + void uncheckAll(); + QStringList checkedFiles(); + void setCheckState(const QString& element, Qt::CheckState); + public slots: void setCheckState(QModelIndex index); void filterChanged(const QString filter); void showContextMenu(const QPoint &point); - void profileChanged(const QString &previous, const QString ¤t); - void profileRenamed(const QString &previous, const QString ¤t); - void updateOkButton(const QString &text); // Action slots - void newProfile(); - void deleteProfile(); // void moveUp(); // void moveDown(); // void moveTop(); @@ -63,12 +57,8 @@ private: QTableView *mMastersTable; QTableView *mPluginsTable; - QToolBar *mProfileToolBar; QMenu *mContextMenu; - QAction *mNewProfileAction; - QAction *mDeleteProfileAction; - // QAction *mMoveUpAction; // QAction *mMoveDownAction; // QAction *mMoveTopAction; @@ -77,20 +67,11 @@ private: QAction *mUncheckAction; Files::ConfigurationManager &mCfgMgr; - Files::PathContainer mDataDirs; - Files::PathContainer mDataLocal; - - QSettings *mLauncherConfig; - - TextInputDialog *mNewProfileDialog; // const QStringList checkedPlugins(); // const QStringList selectedMasters(); void createActions(); - void setupConfig(); - void readConfig(); - }; #endif From 347a734364fa28e045bc1809b3e0a9ca540ca870 Mon Sep 17 00:00:00 2001 From: Michal Sciubidlo Date: Tue, 5 Feb 2013 22:06:36 +0100 Subject: [PATCH 09/18] Move OpenDialog to editor and use it in startup dialogue. Remove debug output from DataFilesList. --- apps/opencs/editor.cpp | 32 +++++++++++----------- apps/opencs/editor.hpp | 3 ++ apps/opencs/view/doc/view.cpp | 29 ++------------------ apps/opencs/view/doc/view.hpp | 5 ---- components/fileorderlist/datafileslist.cpp | 2 -- 5 files changed, 21 insertions(+), 50 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 7156db94e7..02b494d3db 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -15,6 +15,8 @@ CS::Editor::Editor() : mViewManager (mDocumentManager), mNewDocumentIndex (0) connect (&mStartup, SIGNAL (createDocument()), this, SLOT (createDocument ())); connect (&mStartup, SIGNAL (loadDocument()), this, SLOT (loadDocument ())); + + connect (&mOpenDialog, SIGNAL(accepted()), this, SLOT(openFiles())); } void CS::Editor::createDocument() @@ -36,26 +38,24 @@ void CS::Editor::createDocument() } void CS::Editor::loadDocument() +{ + mOpenDialog.show(); + mOpenDialog.raise(); + mOpenDialog.activateWindow(); +} + +void CS::Editor::openFiles() { mStartup.hide(); - - /// \todo open the ESX picker instead - /// \todo remove the manual record creation and load the ESX files instead - - std::ostringstream stream; - - stream << "Document" << (++mNewDocumentIndex); - - std::vector files; - files.push_back (stream.str()); - - CSMDoc::Document *document = mDocumentManager.addDocument (files, false); - + std::vector paths; + mOpenDialog.getFileList(paths); + CSMDoc::Document *document = mDocumentManager.addDocument(paths, false); + static const char *sGlobals[] = { "Day", "DaysPassed", "GameHour", "Month", "PCRace", "PCVampire", "PCWerewolf", "PCYear", 0 }; - + for (int i=0; sGlobals[i]; ++i) { ESM::Global record; @@ -64,9 +64,9 @@ void CS::Editor::loadDocument() record.mType = ESM::VT_Float; document->getData().getGlobals().add (record); } - + document->getData().merge(); /// \todo remove once proper ESX loading is implemented - + mViewManager.addView (document); } diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 0cd780f7fc..024475bf01 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -7,6 +7,7 @@ #include "view/doc/viewmanager.hpp" #include "view/doc/startup.hpp" +#include "view/doc/opendialog.hpp" namespace CS { @@ -19,6 +20,7 @@ namespace CS CSMDoc::DocumentManager mDocumentManager; CSVDoc::ViewManager mViewManager; CSVDoc::StartupDialogue mStartup; + OpenDialog mOpenDialog; // not implemented Editor (const Editor&); @@ -36,6 +38,7 @@ namespace CS void createDocument(); void loadDocument(); + void openFiles(); }; } diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index 146e6634e4..f5cc3d85b0 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -14,7 +14,6 @@ #include "../tools/subviews.hpp" -#include "opendialog.hpp" #include "viewmanager.hpp" #include "operations.hpp" #include "subview.hpp" @@ -32,12 +31,8 @@ void CSVDoc::View::setupFileMenu() QAction *new_ = new QAction (tr ("New"), this); connect (new_, SIGNAL (triggered()), this, SIGNAL (newDocumentRequest())); file->addAction (new_); - - mOpen = new QAction(tr ("&Open"), this); - connect (mOpen, SIGNAL (triggered()), this, SLOT (open())); - file->addAction (mOpen); - QAction *open = new QAction (tr ("Open"), this); + QAction *open = new QAction (tr ("&Open"), this); connect (open, SIGNAL (triggered()), this, SIGNAL (loadDocumentRequest())); file->addAction (open); @@ -119,7 +114,7 @@ void CSVDoc::View::updateActions() } CSVDoc::View::View (ViewManager& viewManager, CSMDoc::Document *document, int totalViews) -: mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), mViewTotal (totalViews), mOpenDialog(0) +: mViewManager (viewManager), mDocument (document), mViewIndex (totalViews-1), mViewTotal (totalViews) { setDockOptions (QMainWindow::AllowNestedDocks); @@ -214,26 +209,6 @@ void CSVDoc::View::save() mDocument->save(); } -void CSVDoc::View::open() -{ - if (!mOpenDialog) { - mOpenDialog = new OpenDialog(this); - connect(mOpenDialog, SIGNAL(accepted()), this, SLOT(openNewFiles())); - } - - mOpenDialog->show(); - mOpenDialog->raise(); - mOpenDialog->activateWindow(); -} - -void CSVDoc::View::openNewFiles() -{ - std::vector paths; - mOpenDialog->getFileList(paths); - //FIXME load new files - -} - void CSVDoc::View::verify() { addSubView (mDocument->verify()); diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index bb3763bb94..05d7210dce 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -9,7 +9,6 @@ #include "subviewfactory.hpp" class QAction; -class OpenDialog; namespace CSMDoc { @@ -37,12 +36,10 @@ namespace CSVDoc QAction *mUndo; QAction *mRedo; QAction *mSave; - QAction *mOpen; QAction *mVerify; std::vector mEditingActions; Operations *mOperations; SubViewFactoryManager mSubViewFactory; - OpenDialog * mOpenDialog; // not implemented View (const View&); @@ -97,8 +94,6 @@ namespace CSVDoc void newView(); - void open(); - void openNewFiles(); void save(); void verify(); diff --git a/components/fileorderlist/datafileslist.cpp b/components/fileorderlist/datafileslist.cpp index 38e0bfb1a5..d25060baaf 100644 --- a/components/fileorderlist/datafileslist.cpp +++ b/components/fileorderlist/datafileslist.cpp @@ -204,13 +204,11 @@ void DataFilesList::selectedFiles(std::vector& paths) foreach (const QString &path, masterPaths) { paths.push_back(path.toStdString()); - cerr << path.toStdString() << endl; } QStringList pluginPaths = mPluginsModel->checkedItemsPaths(); foreach (const QString &path, pluginPaths) { paths.push_back(path.toStdString()); - cerr << path.toStdString() << endl; } } From 7d112e4d5c033b358638fb89255b4da9f5ed12fe Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 7 Feb 2013 11:33:08 +0100 Subject: [PATCH 10/18] rewrote logic of content file loading --- apps/opencs/model/doc/document.cpp | 28 ++++++++++++++++++---------- apps/opencs/model/doc/document.hpp | 3 ++- apps/opencs/model/world/data.cpp | 5 +++++ apps/opencs/model/world/data.hpp | 5 +++++ 4 files changed, 30 insertions(+), 11 deletions(-) diff --git a/apps/opencs/model/doc/document.cpp b/apps/opencs/model/doc/document.cpp index 14e34d0baf..796135c3ff 100644 --- a/apps/opencs/model/doc/document.cpp +++ b/apps/opencs/model/doc/document.cpp @@ -1,15 +1,23 @@ #include "document.hpp" -#include +#include void CSMDoc::Document::load (const std::vector::const_iterator& begin, - const std::vector::const_iterator& end) + const std::vector::const_iterator& end, bool lastAsModified) { - for (std::vector::const_iterator iter (begin); iter!=end; ++iter) - std::cout << "pretending to load " << iter->string() << std::endl; + assert (begin!=end); - /// \todo load content files + std::vector::const_iterator end2 (end); + + if (lastAsModified) + --end2; + + for (std::vector::const_iterator iter (begin); iter!=end2; ++iter) + getData().loadFile (*iter, true); + + if (lastAsModified) + getData().loadFile (*end2, false); } void CSMDoc::Document::createBase() @@ -48,7 +56,7 @@ CSMDoc::Document::Document (const std::vector& files, b if (new_) --end; - load (files.begin(), end); + load (files.begin(), end, !new_); } if (new_ && files.size()==1) @@ -134,10 +142,10 @@ void CSMDoc::Document::saving() if (mSaveCount>15) { - mSaveCount = 0; - mSaveTimer.stop(); - mUndoStack.setClean(); - emit stateChanged (getState(), this); + mSaveCount = 0; + mSaveTimer.stop(); + mUndoStack.setClean(); + emit stateChanged (getState(), this); } } diff --git a/apps/opencs/model/doc/document.hpp b/apps/opencs/model/doc/document.hpp index 28cc19d449..0162681bcb 100644 --- a/apps/opencs/model/doc/document.hpp +++ b/apps/opencs/model/doc/document.hpp @@ -41,7 +41,8 @@ namespace CSMDoc Document& operator= (const Document&); void load (const std::vector::const_iterator& begin, - const std::vector::const_iterator& end); + const std::vector::const_iterator& end, bool lastAsModified); + ///< \param lastAsModified Store the last file in Modified instead of merging it into Base. void createBase(); diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index a3522503e4..5d4e63b277 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -59,4 +59,9 @@ QAbstractTableModel *CSMWorld::Data::getTableModel (const UniversalId& id) void CSMWorld::Data::merge() { mGlobals.merge(); +} + +void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base) +{ + std::cout << "pretending to load " << path.string() << std::endl; } \ No newline at end of file diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index f7748cb5da..8a6cd736b4 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -4,6 +4,8 @@ #include #include +#include + #include #include "idcollection.hpp" @@ -44,6 +46,9 @@ namespace CSMWorld void merge(); ///< Merge modified into base. + + void loadFile (const boost::filesystem::path& path, bool base); + ///< Merging content of a file into base or modified. }; } From adcaea464bda920b74ce9eea527eb4b004e41531 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 7 Feb 2013 12:52:01 +0100 Subject: [PATCH 11/18] basic globals record loading --- apps/opencs/editor.cpp | 20 ++--------- apps/opencs/model/world/data.cpp | 24 ++++++++++++- apps/opencs/model/world/idcollection.cpp | 2 +- apps/opencs/model/world/idcollection.hpp | 45 ++++++++++++++++++++++-- 4 files changed, 69 insertions(+), 22 deletions(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 02b494d3db..9161072f80 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -15,7 +15,7 @@ CS::Editor::Editor() : mViewManager (mDocumentManager), mNewDocumentIndex (0) connect (&mStartup, SIGNAL (createDocument()), this, SLOT (createDocument ())); connect (&mStartup, SIGNAL (loadDocument()), this, SLOT (loadDocument ())); - + connect (&mOpenDialog, SIGNAL(accepted()), this, SLOT(openFiles())); } @@ -50,23 +50,7 @@ void CS::Editor::openFiles() std::vector paths; mOpenDialog.getFileList(paths); CSMDoc::Document *document = mDocumentManager.addDocument(paths, false); - - static const char *sGlobals[] = - { - "Day", "DaysPassed", "GameHour", "Month", "PCRace", "PCVampire", "PCWerewolf", "PCYear", 0 - }; - - for (int i=0; sGlobals[i]; ++i) - { - ESM::Global record; - record.mId = sGlobals[i]; - record.mValue = i==0 ? 1 : 0; - record.mType = ESM::VT_Float; - document->getData().getGlobals().add (record); - } - - document->getData().merge(); /// \todo remove once proper ESX loading is implemented - + mViewManager.addView (document); } diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 5d4e63b277..9b89533a64 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -5,6 +5,7 @@ #include +#include #include #include "idtable.hpp" @@ -63,5 +64,26 @@ void CSMWorld::Data::merge() void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base) { - std::cout << "pretending to load " << path.string() << std::endl; + ESM::ESMReader reader; + /// \todo set encoder + reader.open (path.string()); + + // Note: We do not need to send update signals here, because at this point the model is not connected + // to any view. + while (reader.hasMoreRecs()) + { + ESM::NAME n = reader.getRecName(); + reader.getRecHeader(); + + switch (n.val) + { + case ESM::REC_GLOB: mGlobals.load (reader, base); break; + + + default: + + /// \todo throw an exception instead, once all records are implemented + reader.skipRecord(); + } + } } \ No newline at end of file diff --git a/apps/opencs/model/world/idcollection.cpp b/apps/opencs/model/world/idcollection.cpp index fc4bb1ef65..5ea9532790 100644 --- a/apps/opencs/model/world/idcollection.cpp +++ b/apps/opencs/model/world/idcollection.cpp @@ -3,4 +3,4 @@ CSMWorld::IdCollectionBase::IdCollectionBase() {} -CSMWorld::IdCollectionBase::~IdCollectionBase() {} \ No newline at end of file +CSMWorld::IdCollectionBase::~IdCollectionBase() {} diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index 963997924a..dd8fbcb382 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -11,9 +11,12 @@ #include -#include "columnbase.hpp" +#include + #include +#include "columnbase.hpp" + namespace CSMWorld { class IdCollectionBase @@ -67,9 +70,11 @@ namespace CSMWorld virtual std::string getId (const RecordBase& record) const = 0; ///< Return ID for \a record. /// - /// \attention Throw san exception, if the type of \a record does not match. + /// \attention Throws an exception, if the type of \a record does not match. virtual const RecordBase& getRecord (const std::string& id) const = 0; + + virtual void load (ESM::ESMReader& reader, bool base) = 0; }; ///< \brief Collection of ID-based records @@ -136,6 +141,8 @@ namespace CSMWorld virtual const RecordBase& getRecord (const std::string& id) const; + virtual void load (ESM::ESMReader& reader, bool base); + void addColumn (Column *column); }; @@ -309,6 +316,40 @@ namespace CSMWorld return (record2.isModified() ? record2.mModified : record2.mBase).mId; } + template + void IdCollection::load (ESM::ESMReader& reader, bool base) + { + std::string id = reader.getHNOString ("NAME"); + + /// \todo deal with deleted flag + + ESXRecordT record; + record.mId = id; + record.load (reader); + + int index = searchId (id); + + if (index==-1) + { + // new record + Record record2; + record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; + (base ? record2.mBase : record2.mModified) = record; + + appendRecord (record2); + } + else + { + // old record + Record& record2 = mRecords[index]; + + if (base) + record2.mBase = record; + else + record2.setModified (record); + } + } + template const RecordBase& IdCollection::getRecord (const std::string& id) const { From 21733e8181e11d23fc9358d6de2ca9fb61009d89 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 7 Feb 2013 13:11:41 +0100 Subject: [PATCH 12/18] hide startup dialogue when opening open dialogue --- apps/opencs/editor.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 9161072f80..5cc659ff99 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -39,6 +39,7 @@ void CS::Editor::createDocument() void CS::Editor::loadDocument() { + mStartup.hide(); mOpenDialog.show(); mOpenDialog.raise(); mOpenDialog.activateWindow(); From c1cd8305bc9a01c2871aa097c6ad004dea8743c0 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 7 Feb 2013 13:13:06 +0100 Subject: [PATCH 13/18] a bit of cleanup for the previous commit --- apps/opencs/editor.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index 5cc659ff99..e2df365a29 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -47,7 +47,6 @@ void CS::Editor::loadDocument() void CS::Editor::openFiles() { - mStartup.hide(); std::vector paths; mOpenDialog.getFileList(paths); CSMDoc::Document *document = mDocumentManager.addDocument(paths, false); From dd2b7d5c63a050acf26a82399aecf9f967429b62 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Thu, 7 Feb 2013 13:26:00 +0100 Subject: [PATCH 14/18] handle deleted records --- apps/opencs/model/world/idcollection.hpp | 56 +++++++++++++++++------- 1 file changed, 39 insertions(+), 17 deletions(-) diff --git a/apps/opencs/model/world/idcollection.hpp b/apps/opencs/model/world/idcollection.hpp index dd8fbcb382..5a1d21ae4c 100644 --- a/apps/opencs/model/world/idcollection.hpp +++ b/apps/opencs/model/world/idcollection.hpp @@ -321,32 +321,54 @@ namespace CSMWorld { std::string id = reader.getHNOString ("NAME"); - /// \todo deal with deleted flag - - ESXRecordT record; - record.mId = id; - record.load (reader); - int index = searchId (id); - if (index==-1) + if (reader.isNextSub ("DELE")) { - // new record - Record record2; - record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; - (base ? record2.mBase : record2.mModified) = record; + reader.skipRecord(); - appendRecord (record2); + if (index==-1) + { + // deleting a record that does not exist + + // ignore it for now + + /// \todo report the problem to the user + } + else if (base) + { + removeRows (index, 1); + } + else + { + mRecords[index].mState = RecordBase::State_Deleted; + } } else { - // old record - Record& record2 = mRecords[index]; + ESXRecordT record; + record.mId = id; + record.load (reader); - if (base) - record2.mBase = record; + if (index==-1) + { + // new record + Record record2; + record2.mState = base ? RecordBase::State_BaseOnly : RecordBase::State_ModifiedOnly; + (base ? record2.mBase : record2.mModified) = record; + + appendRecord (record2); + } else - record2.setModified (record); + { + // old record + Record& record2 = mRecords[index]; + + if (base) + record2.mBase = record; + else + record2.setModified (record); + } } } From d5dd0640c7354661c9e660aef17680efbc1b2a8c Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 8 Feb 2013 09:58:19 +0100 Subject: [PATCH 15/18] basic gmst support --- apps/opencs/model/world/data.cpp | 7 +++++++ apps/opencs/model/world/data.hpp | 2 ++ apps/opencs/model/world/universalid.cpp | 2 ++ apps/opencs/model/world/universalid.hpp | 6 +++--- apps/opencs/view/doc/view.cpp | 9 +++++++++ apps/opencs/view/doc/view.hpp | 2 ++ apps/opencs/view/world/subviews.cpp | 3 +++ components/esm/loadgmst.cpp | 23 ++++++++++++++++++++++- components/esm/loadgmst.hpp | 11 ++++++++--- 9 files changed, 58 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 9b89533a64..89c19f0328 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -28,7 +28,13 @@ CSMWorld::Data::Data() mGlobals.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Global)); mGlobals.addColumn (new FloatValueColumn); + mGmsts.addColumn (new StringIdColumn); + mGmsts.addColumn (new RecordStateColumn); + mGmsts.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Gmst)); + ///< \todo add type and value + addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global); + addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst); } CSMWorld::Data::~Data() @@ -78,6 +84,7 @@ void CSMWorld::Data::loadFile (const boost::filesystem::path& path, bool base) switch (n.val) { case ESM::REC_GLOB: mGlobals.load (reader, base); break; + case ESM::REC_GMST: mGmsts.load (reader, base); break; default: diff --git a/apps/opencs/model/world/data.hpp b/apps/opencs/model/world/data.hpp index 8a6cd736b4..519817a3b4 100644 --- a/apps/opencs/model/world/data.hpp +++ b/apps/opencs/model/world/data.hpp @@ -7,6 +7,7 @@ #include #include +#include #include "idcollection.hpp" #include "universalid.hpp" @@ -18,6 +19,7 @@ namespace CSMWorld class Data { IdCollection mGlobals; + IdCollection mGmsts; std::vector mModels; std::map mModelIndex; diff --git a/apps/opencs/model/world/universalid.cpp b/apps/opencs/model/world/universalid.cpp index d8775643ac..c006852bc6 100644 --- a/apps/opencs/model/world/universalid.cpp +++ b/apps/opencs/model/world/universalid.cpp @@ -18,6 +18,7 @@ namespace { { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, "empty" }, { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Globals, "Global Variables" }, + { CSMWorld::UniversalId::Class_RecordList, CSMWorld::UniversalId::Type_Gmsts, "Game Settings" }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker }; @@ -25,6 +26,7 @@ namespace static const TypeData sIdArg[] = { { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Global, "Global Variable" }, + { CSMWorld::UniversalId::Class_Record, CSMWorld::UniversalId::Type_Gmst, "Game Setting" }, { CSMWorld::UniversalId::Class_None, CSMWorld::UniversalId::Type_None, 0 } // end marker }; diff --git a/apps/opencs/model/world/universalid.hpp b/apps/opencs/model/world/universalid.hpp index 4a73feb12c..9ff7d17b18 100644 --- a/apps/opencs/model/world/universalid.hpp +++ b/apps/opencs/model/world/universalid.hpp @@ -33,12 +33,12 @@ namespace CSMWorld enum Type { Type_None, - Type_Globals, - Type_Global, + Type_VerificationResults, + Type_Gmsts, + Type_Gmst - Type_VerificationResults }; private: diff --git a/apps/opencs/view/doc/view.cpp b/apps/opencs/view/doc/view.cpp index f5cc3d85b0..4fd03041f8 100644 --- a/apps/opencs/view/doc/view.cpp +++ b/apps/opencs/view/doc/view.cpp @@ -71,6 +71,10 @@ void CSVDoc::View::setupWorldMenu() connect (globals, SIGNAL (triggered()), this, SLOT (addGlobalsSubView())); world->addAction (globals); + QAction *gmsts = new QAction (tr ("Game settings"), this); + connect (gmsts, SIGNAL (triggered()), this, SLOT (addGmstsSubView())); + world->addAction (gmsts); + mVerify = new QAction (tr ("&Verify"), this); connect (mVerify, SIGNAL (triggered()), this, SLOT (verify())); world->addAction (mVerify); @@ -217,4 +221,9 @@ void CSVDoc::View::verify() void CSVDoc::View::addGlobalsSubView() { addSubView (CSMWorld::UniversalId::Type_Globals); +} + +void CSVDoc::View::addGmstsSubView() +{ + addSubView (CSMWorld::UniversalId::Type_Gmsts); } \ No newline at end of file diff --git a/apps/opencs/view/doc/view.hpp b/apps/opencs/view/doc/view.hpp index 05d7210dce..6bdd54e6bf 100644 --- a/apps/opencs/view/doc/view.hpp +++ b/apps/opencs/view/doc/view.hpp @@ -99,6 +99,8 @@ namespace CSVDoc void verify(); void addGlobalsSubView(); + + void addGmstsSubView(); }; } diff --git a/apps/opencs/view/world/subviews.cpp b/apps/opencs/view/world/subviews.cpp index 080a175ea5..351007ded5 100644 --- a/apps/opencs/view/world/subviews.cpp +++ b/apps/opencs/view/world/subviews.cpp @@ -11,6 +11,9 @@ void CSVWorld::addSubViewFactories (CSVDoc::SubViewFactoryManager& manager) manager.add (CSMWorld::UniversalId::Type_Globals, new CSVDoc::SubViewFactoryWithCreateFlag (true)); + manager.add (CSMWorld::UniversalId::Type_Gmsts, + new CSVDoc::SubViewFactoryWithCreateFlag (false)); + manager.add (CSMWorld::UniversalId::Type_Global, new CSVDoc::SubViewFactoryWithCreateFlag (true)); } \ No newline at end of file diff --git a/components/esm/loadgmst.cpp b/components/esm/loadgmst.cpp index a73095a66a..e9852ec076 100644 --- a/components/esm/loadgmst.cpp +++ b/components/esm/loadgmst.cpp @@ -76,8 +76,29 @@ std::string GameSetting::getString() const { if (mType==VT_String) return mStr; - + throw std::runtime_error ("GMST " + mId + " is not a string"); } + void GameSetting::blank() + { + mStr.clear(); + mI = 0; + mF = 0; + mType = VT_Float; + } + + bool operator== (const GameSetting& left, const GameSetting& right) + { + if (left.mType!=right.mType) + return false; + + switch (left.mType) + { + case VT_Float: return left.mF==right.mF; + case VT_Int: return left.mI==right.mI; + case VT_String: return left.mStr==right.mStr; + default: return false; + } + } } diff --git a/components/esm/loadgmst.hpp b/components/esm/loadgmst.hpp index ab9a9551e5..f7aec5c76c 100644 --- a/components/esm/loadgmst.hpp +++ b/components/esm/loadgmst.hpp @@ -26,17 +26,22 @@ struct GameSetting VarType mType; void load(ESMReader &esm); - + int getInt() const; ///< Throws an exception if GMST is not of type int or float. - + float getFloat() const; ///< Throws an exception if GMST is not of type int or float. - + std::string getString() const; ///< Throwns an exception if GMST is not of type string. void save(ESMWriter &esm); + + void blank(); + ///< Set record to default state (does not touch the ID). }; + + bool operator== (const GameSetting& left, const GameSetting& right); } #endif From cce2d63433a137fa47856670bc433291e4321852 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 8 Feb 2013 12:20:03 +0100 Subject: [PATCH 16/18] added type column to gmst table --- apps/opencs/model/world/columns.hpp | 23 +++++++++++++++++++++++ apps/opencs/model/world/data.cpp | 3 ++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 1e2de92658..7473876763 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -91,6 +91,29 @@ namespace CSMWorld return false; } }; + + template + struct VarTypeColumn : public Column + { + VarTypeColumn() : Column ("Type", ColumnBase::Display_Float) {} + + virtual QVariant get (const Record& record) const + { + return static_cast (record.get().mType); + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT base = record.getBase(); + base.mType = static_cast (data.toInt()); + record.setModified (base); + } + + virtual bool isEditable() const + { + return true; + } + }; } #endif \ No newline at end of file diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 89c19f0328..69e62db018 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -31,7 +31,8 @@ CSMWorld::Data::Data() mGmsts.addColumn (new StringIdColumn); mGmsts.addColumn (new RecordStateColumn); mGmsts.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Gmst)); - ///< \todo add type and value + mGmsts.addColumn (new VarTypeColumn); + ///< \todo add value addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global); addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst); From 828695f295e07cd9ece9cbc6333a83c49cf033b3 Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Fri, 8 Feb 2013 14:48:38 +0100 Subject: [PATCH 17/18] added value column to gmst table --- apps/opencs/model/world/columnbase.hpp | 3 +- apps/opencs/model/world/columns.hpp | 41 +++++++++++++++++++++- apps/opencs/model/world/data.cpp | 2 +- apps/opencs/view/world/dialoguesubview.cpp | 4 +++ 4 files changed, 47 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/world/columnbase.hpp b/apps/opencs/model/world/columnbase.hpp index 38b73ee3f5..f1871a6a94 100644 --- a/apps/opencs/model/world/columnbase.hpp +++ b/apps/opencs/model/world/columnbase.hpp @@ -28,7 +28,8 @@ namespace CSMWorld { Display_String, Display_Integer, - Display_Float + Display_Float, + Display_Var }; std::string mTitle; diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index 7473876763..fb94cbf591 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -95,7 +95,7 @@ namespace CSMWorld template struct VarTypeColumn : public Column { - VarTypeColumn() : Column ("Type", ColumnBase::Display_Float) {} + VarTypeColumn() : Column ("Type", ColumnBase::Display_Integer) {} virtual QVariant get (const Record& record) const { @@ -114,6 +114,45 @@ namespace CSMWorld return true; } }; + + template + struct VarValueColumn : public Column + { + VarValueColumn() : Column ("Value", ColumnBase::Display_Var) {} + + virtual QVariant get (const Record& record) const + { + switch (record.get().mType) + { + case ESM::VT_String: return record.get().mStr.c_str(); break; + case ESM::VT_Int: return record.get().mI; break; + case ESM::VT_Float: return record.get().mF; break; + + default: return QVariant(); + } + } + + virtual void set (Record& record, const QVariant& data) + { + ESXRecordT base = record.getBase(); + + switch (record.get().mType) + { + case ESM::VT_String: base.mStr = data.toString().toUtf8().constData(); break; + case ESM::VT_Int: base.mI = data.toInt(); break; + case ESM::VT_Float: base.mF = data.toFloat(); break; + + default: break; + } + + record.setModified (base); + } + + virtual bool isEditable() const + { + return true; + } + }; } #endif \ No newline at end of file diff --git a/apps/opencs/model/world/data.cpp b/apps/opencs/model/world/data.cpp index 69e62db018..f120c75f10 100644 --- a/apps/opencs/model/world/data.cpp +++ b/apps/opencs/model/world/data.cpp @@ -32,7 +32,7 @@ CSMWorld::Data::Data() mGmsts.addColumn (new RecordStateColumn); mGmsts.addColumn (new FixedRecordTypeColumn (UniversalId::Type_Gmst)); mGmsts.addColumn (new VarTypeColumn); - ///< \todo add value + mGmsts.addColumn (new VarValueColumn); addModel (new IdTable (&mGlobals), UniversalId::Type_Globals, UniversalId::Type_Global); addModel (new IdTable (&mGmsts), UniversalId::Type_Gmsts, UniversalId::Type_Gmst); diff --git a/apps/opencs/view/world/dialoguesubview.cpp b/apps/opencs/view/world/dialoguesubview.cpp index 2bf6577b11..e16de99eff 100644 --- a/apps/opencs/view/world/dialoguesubview.cpp +++ b/apps/opencs/view/world/dialoguesubview.cpp @@ -64,6 +64,8 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM /// \todo configure widget properly (range, format?) layout->addWidget (widget = new QDoubleSpinBox, i, 1); break; + + default: break; // silence warnings for other times for now } } else @@ -76,6 +78,8 @@ CSVWorld::DialogueSubView::DialogueSubView (const CSMWorld::UniversalId& id, CSM layout->addWidget (widget = new QLabel, i, 1); break; + + default: break; // silence warnings for other times for now } } From d40ee068975ec80a5acecc7ca686772a554106dd Mon Sep 17 00:00:00 2001 From: Marc Zinnschlag Date: Sat, 9 Feb 2013 15:25:50 +0100 Subject: [PATCH 18/18] fixed base/modified logic --- apps/opencs/model/world/columns.hpp | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/apps/opencs/model/world/columns.hpp b/apps/opencs/model/world/columns.hpp index fb94cbf591..cfbd804a5a 100644 --- a/apps/opencs/model/world/columns.hpp +++ b/apps/opencs/model/world/columns.hpp @@ -17,9 +17,9 @@ namespace CSMWorld virtual void set (Record& record, const QVariant& data) { - ESXRecordT base = record.getBase(); - base.mValue = data.toFloat(); - record.setModified (base); + ESXRecordT record2 = record.get(); + record2.mValue = data.toFloat(); + record.setModified (record2); } virtual bool isEditable() const @@ -104,9 +104,9 @@ namespace CSMWorld virtual void set (Record& record, const QVariant& data) { - ESXRecordT base = record.getBase(); - base.mType = static_cast (data.toInt()); - record.setModified (base); + ESXRecordT record2 = record.get(); + record2.mType = static_cast (data.toInt()); + record.setModified (record2); } virtual bool isEditable() const @@ -134,18 +134,18 @@ namespace CSMWorld virtual void set (Record& record, const QVariant& data) { - ESXRecordT base = record.getBase(); + ESXRecordT record2 = record.get(); - switch (record.get().mType) + switch (record2.mType) { - case ESM::VT_String: base.mStr = data.toString().toUtf8().constData(); break; - case ESM::VT_Int: base.mI = data.toInt(); break; - case ESM::VT_Float: base.mF = data.toFloat(); break; + case ESM::VT_String: record2.mStr = data.toString().toUtf8().constData(); break; + case ESM::VT_Int: record2.mI = data.toInt(); break; + case ESM::VT_Float: record2.mF = data.toFloat(); break; default: break; } - record.setModified (base); + record.setModified (record2); } virtual bool isEditable() const