From 7504ae675b44c4ebea2509d8ef3e8381200111d3 Mon Sep 17 00:00:00 2001 From: Pieter van der Kloet Date: Thu, 7 Mar 2013 03:00:59 +0100 Subject: [PATCH] Implemented a file dialog for the editor using launcher .ui --- apps/launcher/CMakeLists.txt | 16 +- apps/launcher/datafilespage.cpp | 60 +--- apps/launcher/resources.qrc | 21 -- apps/opencs/CMakeLists.txt | 6 +- apps/opencs/editor.cpp | 95 ++++-- apps/opencs/editor.hpp | 15 +- apps/opencs/view/doc/filedialog.cpp | 272 ++++++++++++++++ apps/opencs/view/doc/filedialog.hpp | 66 ++++ components/CMakeLists.txt | 2 +- components/fileorderlist/datafileslist.cpp | 293 ------------------ components/fileorderlist/datafileslist.hpp | 75 ----- .../fileorderlist/model/datafilesmodel.cpp | 1 + .../fileorderlist/model/datafilesmodel.hpp | 3 + .../model/pluginsproxymodel.cpp | 0 .../model/pluginsproxymodel.hpp | 0 .../launcher}/icons/tango/document-new.png | Bin .../launcher}/icons/tango/edit-copy.png | Bin .../launcher}/icons/tango/edit-delete.png | Bin .../launcher}/icons/tango/go-bottom.png | Bin .../launcher}/icons/tango/go-down.png | Bin .../launcher}/icons/tango/go-top.png | Bin .../launcher}/icons/tango/go-up.png | Bin .../launcher}/icons/tango/index.theme | 0 .../launcher}/icons/tango/video-display.png | Bin .../launcher}/images/clear.png | Bin .../launcher}/images/down.png | Bin .../launcher}/images/openmw-header.png | Bin .../launcher}/images/openmw-plugin.png | Bin .../launcher}/images/openmw.ico | Bin .../launcher}/images/openmw.png | Bin .../launcher}/images/playpage-background.png | Bin files/launcher/launcher.qrc | 21 ++ {apps/launcher => files}/ui/datafilespage.ui | 2 +- {apps/launcher => files}/ui/graphicspage.ui | 0 {apps/launcher => files}/ui/mainwindow.ui | 0 {apps/launcher => files}/ui/playpage.ui | 0 36 files changed, 461 insertions(+), 487 deletions(-) delete mode 100644 apps/launcher/resources.qrc create mode 100644 apps/opencs/view/doc/filedialog.cpp create mode 100644 apps/opencs/view/doc/filedialog.hpp delete mode 100644 components/fileorderlist/datafileslist.cpp delete mode 100644 components/fileorderlist/datafileslist.hpp rename {apps/launcher => components/fileorderlist}/model/pluginsproxymodel.cpp (100%) rename {apps/launcher => components/fileorderlist}/model/pluginsproxymodel.hpp (100%) rename {apps/launcher/resources => files/launcher}/icons/tango/document-new.png (100%) rename {apps/launcher/resources => files/launcher}/icons/tango/edit-copy.png (100%) rename {apps/launcher/resources => files/launcher}/icons/tango/edit-delete.png (100%) rename {apps/launcher/resources => files/launcher}/icons/tango/go-bottom.png (100%) rename {apps/launcher/resources => files/launcher}/icons/tango/go-down.png (100%) rename {apps/launcher/resources => files/launcher}/icons/tango/go-top.png (100%) rename {apps/launcher/resources => files/launcher}/icons/tango/go-up.png (100%) rename {apps/launcher/resources => files/launcher}/icons/tango/index.theme (100%) rename {apps/launcher/resources => files/launcher}/icons/tango/video-display.png (100%) rename {apps/launcher/resources => files/launcher}/images/clear.png (100%) rename {apps/launcher/resources => files/launcher}/images/down.png (100%) rename {apps/launcher/resources => files/launcher}/images/openmw-header.png (100%) rename {apps/launcher/resources => files/launcher}/images/openmw-plugin.png (100%) rename {apps/launcher/resources => files/launcher}/images/openmw.ico (100%) rename {apps/launcher/resources => files/launcher}/images/openmw.png (100%) rename {apps/launcher/resources => files/launcher}/images/playpage-background.png (100%) create mode 100644 files/launcher/launcher.qrc rename {apps/launcher => files}/ui/datafilespage.ui (98%) rename {apps/launcher => files}/ui/graphicspage.ui (100%) rename {apps/launcher => files}/ui/mainwindow.ui (100%) rename {apps/launcher => files}/ui/playpage.ui (100%) diff --git a/apps/launcher/CMakeLists.txt b/apps/launcher/CMakeLists.txt index a1c228945..a63898c0e 100644 --- a/apps/launcher/CMakeLists.txt +++ b/apps/launcher/CMakeLists.txt @@ -5,8 +5,6 @@ set(LAUNCHER maindialog.cpp playpage.cpp - model/pluginsproxymodel.cpp - settings/gamesettings.cpp settings/graphicssettings.cpp settings/launchersettings.cpp @@ -23,8 +21,6 @@ set(LAUNCHER_HEADER maindialog.hpp playpage.hpp - model/pluginsproxymodel.hpp - settings/gamesettings.hpp settings/graphicssettings.hpp settings/launchersettings.hpp @@ -42,17 +38,15 @@ set(LAUNCHER_HEADER_MOC maindialog.hpp playpage.hpp - model/pluginsproxymodel.hpp - utils/checkablemessagebox.hpp utils/textinputdialog.hpp ) set(LAUNCHER_UI - ui/datafilespage.ui - ui/graphicspage.ui - ui/mainwindow.ui - ui/playpage.ui + ../../files/ui/datafilespage.ui + ../../files/ui/graphicspage.ui + ../../files/ui/mainwindow.ui + ../../files/ui/playpage.ui ) source_group(launcher FILES ${LAUNCHER} ${LAUNCHER_HEADER}) @@ -66,7 +60,7 @@ if(WIN32) set(QT_USE_QTMAIN TRUE) endif(WIN32) -QT4_ADD_RESOURCES(RCC_SRCS resources.qrc) +QT4_ADD_RESOURCES(RCC_SRCS ${CMAKE_SOURCE_DIR}/files/launcher/launcher.qrc) QT4_WRAP_CPP(MOC_SRCS ${LAUNCHER_HEADER_MOC}) QT4_WRAP_UI(UI_HDRS ${LAUNCHER_UI}) diff --git a/apps/launcher/datafilespage.cpp b/apps/launcher/datafilespage.cpp index 069cdd9ac..90cdd2942 100644 --- a/apps/launcher/datafilespage.cpp +++ b/apps/launcher/datafilespage.cpp @@ -2,25 +2,21 @@ #include -#include #include #include +#include #include #include #include #include -#include "model/pluginsproxymodel.hpp" - #include "settings/gamesettings.hpp" #include "settings/launchersettings.hpp" #include "utils/textinputdialog.hpp" -using namespace ESM; -using namespace std; //sort QModelIndexList ascending bool rowGreaterThan(const QModelIndex &index1, const QModelIndex &index2) @@ -100,60 +96,6 @@ DataFilesPage::DataFilesPage(Files::ConfigurationManager &cfg, GameSettings &gam splitter->setSizes(sizeList); -// // Filter toolbar -// QLabel *filterLabel = new QLabel(tr("&Filter:"), this); -// LineEdit *filterLineEdit = new LineEdit(this); -// filterLabel->setBuddy(filterLineEdit); - -// QToolBar *filterToolBar = new QToolBar(this); -// filterToolBar->setMovable(false); - -// // Create a container widget and a layout to get the spacer to work -// QWidget *filterWidget = new QWidget(this); -// QHBoxLayout *filterLayout = new QHBoxLayout(filterWidget); -// QSpacerItem *hSpacer1 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); - -// filterLayout->addItem(hSpacer1); -// filterLayout->addWidget(filterLabel); -// filterLayout->addWidget(filterLineEdit); - -// filterToolBar->addWidget(filterWidget); - - - -// // Add both tables to a splitter -// mSplitter = new QSplitter(this); -// mSplitter->setOrientation(Qt::Horizontal); -// mSplitter->setChildrenCollapsible(false); // Don't allow the widgets to be hidden -// mSplitter->addWidget(mastersTable); -// mSplitter->addWidget(pluginsTable); - - - -// - -// // Bottom part with profile options -// QLabel *profileLabel = new QLabel(tr("Current Profile: "), this); - -// profilesComboBox = new ProfilesComboBox(this); -// profilesComboBox->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum)); -// profilesComboBox->setInsertPolicy(QComboBox::NoInsert); -// profilesComboBox->setDuplicatesEnabled(false); -// profilesComboBox->setEditEnabled(false); - -// mProfileToolBar = new QToolBar(this); -// mProfileToolBar->setMovable(false); -// mProfileToolBar->setIconSize(QSize(16, 16)); - -// mProfileToolBar->addWidget(profileLabel); -// mProfileToolBar->addWidget(profilesComboBox); - -// QVBoxLayout *pageLayout = new QVBoxLayout(this); - -// pageLayout->addWidget(filterToolBar); -// pageLayout->addWidget(mSplitter); -// pageLayout->addWidget(mProfileToolBar); - // Create a dialog for the new profile name input mNewProfileDialog = new TextInputDialog(tr("New Profile"), tr("Profile name:"), this); diff --git a/apps/launcher/resources.qrc b/apps/launcher/resources.qrc deleted file mode 100644 index 2b56f80fd..000000000 --- a/apps/launcher/resources.qrc +++ /dev/null @@ -1,21 +0,0 @@ - - - resources/images/clear.png - resources/images/down.png - resources/images/openmw.png - resources/images/openmw-plugin.png - resources/images/openmw-header.png - resources/images/playpage-background.png - - - resources/icons/tango/index.theme - resources/icons/tango/video-display.png - resources/icons/tango/document-new.png - resources/icons/tango/edit-copy.png - resources/icons/tango/edit-delete.png - resources/icons/tango/go-bottom.png - resources/icons/tango/go-down.png - resources/icons/tango/go-top.png - resources/icons/tango/go-up.png - - diff --git a/apps/opencs/CMakeLists.txt b/apps/opencs/CMakeLists.txt index d5d389a14..0071dd1fc 100644 --- a/apps/opencs/CMakeLists.txt +++ b/apps/opencs/CMakeLists.txt @@ -41,7 +41,7 @@ opencs_units_noqt (model/tools opencs_units (view/doc - viewmanager view operations operation subview startup opendialog + viewmanager view operations operation subview startup filedialog ) @@ -76,6 +76,10 @@ set (OPENCS_US ) set (OPENCS_RES ../../files/opencs/resources.qrc + ../../files/launcher/launcher.qrc + ) + +set (OPENCS_UI ../../files/ui/datafilespage.ui ) source_group (opencs FILES ${OPENCS_SRC} ${OPENCS_HDR}) diff --git a/apps/opencs/editor.cpp b/apps/opencs/editor.cpp index e2df365a2..5966d089e 100644 --- a/apps/opencs/editor.cpp +++ b/apps/opencs/editor.cpp @@ -1,14 +1,12 @@ #include "editor.hpp" -#include - #include #include "model/doc/document.hpp" #include "model/world/data.hpp" -CS::Editor::Editor() : mViewManager (mDocumentManager), mNewDocumentIndex (0) +CS::Editor::Editor() : mViewManager (mDocumentManager) { connect (&mViewManager, SIGNAL (newDocumentRequest ()), this, SLOT (createDocument ())); connect (&mViewManager, SIGNAL (loadDocumentRequest ()), this, SLOT (loadDocument ())); @@ -16,42 +14,99 @@ 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())); + connect (&mFileDialog, SIGNAL(openFiles()), this, SLOT(openFiles())); + connect (&mFileDialog, SIGNAL(createNewFile()), this, SLOT(createNewFile())); + + setupDataFiles(); } -void CS::Editor::createDocument() +void CS::Editor::setupDataFiles() { - mStartup.hide(); + boost::program_options::variables_map variables; + boost::program_options::options_description desc; - /// \todo open the ESX picker instead + 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")); - std::ostringstream stream; + boost::program_options::notify(variables); - stream << "NewDocument" << (++mNewDocumentIndex); + mCfgMgr.readConfiguration(variables, desc); - std::vector files; - files.push_back (stream.str()); + Files::PathContainer mDataDirs, mDataLocal; + if (!variables["data"].empty()) { + mDataDirs = Files::PathContainer(variables["data"].as()); + } - CSMDoc::Document *document = mDocumentManager.addDocument (files, true); + std::string local = variables["data-local"].as(); + if (!local.empty()) { + mDataLocal.push_back(Files::PathContainer::value_type(local)); + } - mViewManager.addView (document); + mCfgMgr.processPaths(mDataDirs); + mCfgMgr.processPaths(mDataLocal); + + // Set the charset for reading the esm/esp files + QString encoding = QString::fromStdString(variables["encoding"].as()); + mFileDialog.setEncoding(encoding); + + Files::PathContainer dataDirs; + dataDirs.insert(dataDirs.end(), mDataDirs.begin(), mDataDirs.end()); + dataDirs.insert(dataDirs.end(), mDataLocal.begin(), mDataLocal.end()); + + for (Files::PathContainer::const_iterator iter = dataDirs.begin(); iter != dataDirs.end(); ++iter) + { + QString path = QString::fromStdString(iter->string()); + mFileDialog.addFiles(path); + } +} + +void CS::Editor::createDocument() +{ + mStartup.hide(); + + mFileDialog.newFile(); } void CS::Editor::loadDocument() { mStartup.hide(); - mOpenDialog.show(); - mOpenDialog.raise(); - mOpenDialog.activateWindow(); + + mFileDialog.openFile(); } void CS::Editor::openFiles() { - std::vector paths; - mOpenDialog.getFileList(paths); - CSMDoc::Document *document = mDocumentManager.addDocument(paths, false); + std::vector files; + QStringList paths = mFileDialog.checkedItemsPaths(); + + foreach (const QString &path, paths) { + files.push_back(path.toStdString()); + } + + CSMDoc::Document *document = mDocumentManager.addDocument(files, false); mViewManager.addView (document); + mFileDialog.hide(); +} + +void CS::Editor::createNewFile() +{ + std::vector files; + QStringList paths = mFileDialog.checkedItemsPaths(); + + foreach (const QString &path, paths) { + files.push_back(path.toStdString()); + } + + files.push_back(mFileDialog.fileName().toStdString()); + + CSMDoc::Document *document = mDocumentManager.addDocument (files, true); + + mViewManager.addView (document); + mFileDialog.hide(); } int CS::Editor::run() @@ -59,4 +114,4 @@ int CS::Editor::run() mStartup.show(); return QApplication::exec(); -} \ No newline at end of file +} diff --git a/apps/opencs/editor.hpp b/apps/opencs/editor.hpp index 024475bf0..c242a17ea 100644 --- a/apps/opencs/editor.hpp +++ b/apps/opencs/editor.hpp @@ -3,11 +3,13 @@ #include +#include + #include "model/doc/documentmanager.hpp" #include "view/doc/viewmanager.hpp" #include "view/doc/startup.hpp" -#include "view/doc/opendialog.hpp" +#include "view/doc/filedialog.hpp" namespace CS { @@ -15,12 +17,14 @@ namespace CS { Q_OBJECT - int mNewDocumentIndex; ///< \todo remove when the proper new document dialogue is implemented. - CSMDoc::DocumentManager mDocumentManager; CSVDoc::ViewManager mViewManager; CSVDoc::StartupDialogue mStartup; - OpenDialog mOpenDialog; + FileDialog mFileDialog; + + Files::ConfigurationManager mCfgMgr; + + void setupDataFiles(); // not implemented Editor (const Editor&); @@ -39,7 +43,8 @@ namespace CS void loadDocument(); void openFiles(); + void createNewFile(); }; } -#endif \ No newline at end of file +#endif diff --git a/apps/opencs/view/doc/filedialog.cpp b/apps/opencs/view/doc/filedialog.cpp new file mode 100644 index 000000000..f956317a7 --- /dev/null +++ b/apps/opencs/view/doc/filedialog.cpp @@ -0,0 +1,272 @@ +#include "filedialog.hpp" + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include + +FileDialog::FileDialog(QWidget *parent) : + QDialog(parent) +{ + setupUi(this); + + // Models + mDataFilesModel = new DataFilesModel(this); + + mMastersProxyModel = new QSortFilterProxyModel(); + mMastersProxyModel->setFilterRegExp(QString("^.*\\.esm")); + mMastersProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + mMastersProxyModel->setSourceModel(mDataFilesModel); + + mPluginsProxyModel = new PluginsProxyModel(); + mPluginsProxyModel->setFilterRegExp(QString("^.*\\.esp")); + mPluginsProxyModel->setFilterCaseSensitivity(Qt::CaseInsensitive); + mPluginsProxyModel->setSourceModel(mDataFilesModel); + + mFilterProxyModel = new QSortFilterProxyModel(); + mFilterProxyModel->setDynamicSortFilter(true); + mFilterProxyModel->setSourceModel(mPluginsProxyModel); + + QCheckBox checkBox; + unsigned int height = checkBox.sizeHint().height() + 4; + + mastersTable->setModel(mMastersProxyModel); + mastersTable->setObjectName("MastersTable"); + mastersTable->setContextMenuPolicy(Qt::CustomContextMenu); + mastersTable->setSortingEnabled(false); + mastersTable->setSelectionBehavior(QAbstractItemView::SelectRows); + mastersTable->setSelectionMode(QAbstractItemView::ExtendedSelection); + mastersTable->setEditTriggers(QAbstractItemView::NoEditTriggers); + mastersTable->setAlternatingRowColors(true); + mastersTable->horizontalHeader()->setStretchLastSection(true); + + // Set the row height to the size of the checkboxes + mastersTable->verticalHeader()->setDefaultSectionSize(height); + mastersTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); + mastersTable->verticalHeader()->hide(); + + pluginsTable->setModel(mFilterProxyModel); + pluginsTable->setObjectName("PluginsTable"); + pluginsTable->setContextMenuPolicy(Qt::CustomContextMenu); + pluginsTable->setSortingEnabled(false); + pluginsTable->setSelectionBehavior(QAbstractItemView::SelectRows); + pluginsTable->setSelectionMode(QAbstractItemView::ExtendedSelection); + pluginsTable->setEditTriggers(QAbstractItemView::NoEditTriggers); + pluginsTable->setAlternatingRowColors(true); + pluginsTable->setVerticalScrollMode(QAbstractItemView::ScrollPerItem); + pluginsTable->horizontalHeader()->setStretchLastSection(true); + + pluginsTable->verticalHeader()->setDefaultSectionSize(height); + pluginsTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); + + // Hide the profile elements + profileLabel->hide(); + profilesComboBox->hide(); + newProfileButton->hide(); + deleteProfileButton->hide(); + + // Add some extra widgets + QHBoxLayout *nameLayout = new QHBoxLayout(); + QSpacerItem *spacer = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); + + mNameLabel = new QLabel(tr("File Name:"), this); + + QRegExpValidator *validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9\\s]*$")); + mNameLineEdit = new LineEdit(this); + mNameLineEdit->setValidator(validator); + + nameLayout->addSpacerItem(spacer); + nameLayout->addWidget(mNameLabel); + nameLayout->addWidget(mNameLineEdit); + + mButtonBox = new QDialogButtonBox(this); + + mCreateButton = new QPushButton(tr("Create"), this); + mCreateButton->setEnabled(false); + + verticalLayout->addLayout(nameLayout); + verticalLayout->addWidget(mButtonBox); + + // Set sizes + QList sizeList; + sizeList << 175; + sizeList << 200; + + splitter->setSizes(sizeList); + + resize(600, 400); + + connect(mDataFilesModel, SIGNAL(layoutChanged()), this, SLOT(updateViews())); + connect(mDataFilesModel, SIGNAL(checkedItemsChanged(QStringList)), this, SLOT(updateOpenButton(QStringList))); + connect(mNameLineEdit, SIGNAL(textChanged(QString)), this, SLOT(updateCreateButton(QString))); + + connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); + + connect(pluginsTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); + connect(mastersTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); + + connect(mCreateButton, SIGNAL(clicked()), this, SLOT(createButtonClicked())); + + connect(mButtonBox, SIGNAL(accepted()), this, SLOT(accept())); + connect(mButtonBox, SIGNAL(rejected()), this, SLOT(reject())); +} + +void FileDialog::updateViews() +{ + // Ensure the columns are hidden because sort() re-enables them + mastersTable->setColumnHidden(1, true); + mastersTable->setColumnHidden(3, true); + mastersTable->setColumnHidden(4, true); + mastersTable->setColumnHidden(5, true); + mastersTable->setColumnHidden(6, true); + mastersTable->setColumnHidden(7, true); + mastersTable->setColumnHidden(8, true); + mastersTable->resizeColumnsToContents(); + + pluginsTable->setColumnHidden(1, true); + pluginsTable->setColumnHidden(3, true); + pluginsTable->setColumnHidden(4, true); + pluginsTable->setColumnHidden(5, true); + pluginsTable->setColumnHidden(6, true); + pluginsTable->setColumnHidden(7, true); + pluginsTable->setColumnHidden(8, true); + pluginsTable->resizeColumnsToContents(); + +} + +void FileDialog::updateOpenButton(const QStringList &items) +{ + QPushButton *openButton = mButtonBox->button(QDialogButtonBox::Open); + + if (!openButton) + return; + + openButton->setEnabled(!items.isEmpty()); +} + +void FileDialog::updateCreateButton(const QString &name) +{ + if (!mCreateButton->isVisible()) + return; + + mCreateButton->setEnabled(!name.isEmpty()); +} + +void FileDialog::filterChanged(const QString &filter) +{ + QRegExp filterRe(filter, Qt::CaseInsensitive, QRegExp::FixedString); + mFilterProxyModel->setFilterRegExp(filterRe); +} + +void FileDialog::addFiles(const QString &path) +{ + mDataFilesModel->addFiles(path); + mDataFilesModel->sort(3); // Sort by date accessed +} + +void FileDialog::setEncoding(const QString &encoding) +{ + mDataFilesModel->setEncoding(encoding); +} + +void FileDialog::setCheckState(QModelIndex index) +{ + if (!index.isValid()) + return; + + QObject *object = QObject::sender(); + + // Not a signal-slot call + if (!object) + return; + + + if (object->objectName() == QLatin1String("PluginsTable")) { + QModelIndex sourceIndex = mPluginsProxyModel->mapToSource( + mFilterProxyModel->mapToSource(index)); + + if (sourceIndex.isValid()) { + (mDataFilesModel->checkState(sourceIndex) == Qt::Checked) + ? mDataFilesModel->setCheckState(sourceIndex, Qt::Unchecked) + : mDataFilesModel->setCheckState(sourceIndex, Qt::Checked); + } + } + + if (object->objectName() == QLatin1String("MastersTable")) { + QModelIndex sourceIndex = mMastersProxyModel->mapToSource(index); + + if (sourceIndex.isValid()) { + (mDataFilesModel->checkState(sourceIndex) == Qt::Checked) + ? mDataFilesModel->setCheckState(sourceIndex, Qt::Unchecked) + : mDataFilesModel->setCheckState(sourceIndex, Qt::Checked); + } + } + + return; +} + +QStringList FileDialog::checkedItemsPaths() +{ + return mDataFilesModel->checkedItemsPaths(); +} + +QString FileDialog::fileName() +{ + return mNameLineEdit->text(); +} + +void FileDialog::openFile() +{ + setWindowTitle(tr("Open")); + + mNameLabel->hide(); + mNameLineEdit->hide(); + mCreateButton->hide(); + + mButtonBox->removeButton(mCreateButton); + mButtonBox->setStandardButtons(QDialogButtonBox::Cancel | QDialogButtonBox::Open); + QPushButton *openButton = mButtonBox->button(QDialogButtonBox::Open); + openButton->setEnabled(false); + + show(); + raise(); + activateWindow(); +} + +void FileDialog::newFile() +{ + setWindowTitle(tr("New")); + + mNameLabel->show(); + mNameLineEdit->clear(); + mNameLineEdit->show(); + mCreateButton->show(); + + mButtonBox->setStandardButtons(QDialogButtonBox::Cancel); + mButtonBox->addButton(mCreateButton, QDialogButtonBox::ActionRole); + + show(); + raise(); + activateWindow(); +} + +void FileDialog::accept() +{ + emit openFiles(); +} + +void FileDialog::createButtonClicked() +{ + emit createNewFile(); +} diff --git a/apps/opencs/view/doc/filedialog.hpp b/apps/opencs/view/doc/filedialog.hpp new file mode 100644 index 000000000..b21618d5d --- /dev/null +++ b/apps/opencs/view/doc/filedialog.hpp @@ -0,0 +1,66 @@ +#ifndef FILEDIALOG_HPP +#define FILEDIALOG_HPP + +#include +#include + +#include "ui_datafilespage.h" + +class QDialogButtonBox; +class QSortFilterProxyModel; +class QAbstractItemModel; +class QPushButton; +class QStringList; +class QString; +class QMenu; + +class DataFilesModel; +class PluginsProxyModel; + +class FileDialog : public QDialog, private Ui::DataFilesPage +{ + Q_OBJECT +public: + explicit FileDialog(QWidget *parent = 0); + void addFiles(const QString &path); + void setEncoding(const QString &encoding); + + void openFile(); + void newFile(); + void accepted(); + + QStringList checkedItemsPaths(); + QString fileName(); + +signals: + void openFiles(); + void createNewFile(); + +public slots: + void accept(); + +private slots: + void updateViews(); + void updateOpenButton(const QStringList &items); + void updateCreateButton(const QString &name); + void setCheckState(QModelIndex index); + + void filterChanged(const QString &filter); + + void createButtonClicked(); + +private: + QLabel *mNameLabel; + LineEdit *mNameLineEdit; + + QPushButton *mCreateButton; + QDialogButtonBox *mButtonBox; + + DataFilesModel *mDataFilesModel; + + PluginsProxyModel *mPluginsProxyModel; + QSortFilterProxyModel *mMastersProxyModel; + QSortFilterProxyModel *mFilterProxyModel; +}; + +#endif // FILEDIALOG_HPP diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index 7c52ab12c..a4b194fab 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -70,7 +70,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 + model/modelitem model/datafilesmodel model/pluginsproxymodel model/esm/esmfile utils/profilescombobox utils/comboboxlineedit utils/lineedit utils/naturalsort ) diff --git a/components/fileorderlist/datafileslist.cpp b/components/fileorderlist/datafileslist.cpp deleted file mode 100644 index 9fe8d0fea..000000000 --- a/components/fileorderlist/datafileslist.cpp +++ /dev/null @@ -1,293 +0,0 @@ -#include - -#include -#include - -#include "model/datafilesmodel.hpp" -#include "model/esm/esmfile.hpp" - -#include "utils/lineedit.hpp" - -#include "datafileslist.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; - -//sort QModelIndexList ascending -bool rowGreaterThan(const QModelIndex &index1, const QModelIndex &index2) -{ - return index1.row() >= index2.row(); -} - -//sort QModelIndexList descending -bool rowSmallerThan(const QModelIndex &index1, const QModelIndex &index2) -{ - return index1.row() <= index2.row(); -} - -DataFilesList::DataFilesList(Files::ConfigurationManager &cfg, QWidget *parent) - : QWidget(parent) - , mCfgMgr(cfg) -{ - // Model - mFilesModel = new DataFilesModel(this); - - mFilesProxyModel = new QSortFilterProxyModel(); - mFilesProxyModel->setDynamicSortFilter(true); - mFilesProxyModel->setSourceModel(mFilesModel); - - // Filter toolbar - QLabel *filterLabel = new QLabel(tr("&Filter:"), this); - LineEdit *filterLineEdit = new LineEdit(this); - filterLabel->setBuddy(filterLineEdit); - - QToolBar *filterToolBar = new QToolBar(this); - filterToolBar->setMovable(false); - - // Create a container widget and a layout to get the spacer to work - QWidget *filterWidget = new QWidget(this); - QHBoxLayout *filterLayout = new QHBoxLayout(filterWidget); - QSpacerItem *hSpacer1 = new QSpacerItem(40, 20, QSizePolicy::Expanding, QSizePolicy::Minimum); - - filterLayout->addItem(hSpacer1); - filterLayout->addWidget(filterLabel); - filterLayout->addWidget(filterLineEdit); - - filterToolBar->addWidget(filterWidget); - - QCheckBox checkBox; - unsigned int height = checkBox.sizeHint().height() + 4; - - mFilesTable = new QTableView(this); - mFilesTable->setModel(mFilesProxyModel); - mFilesTable->setObjectName("PluginsTable"); - mFilesTable->setContextMenuPolicy(Qt::CustomContextMenu); - mFilesTable->setSelectionBehavior(QAbstractItemView::SelectRows); - mFilesTable->setSelectionMode(QAbstractItemView::SingleSelection); - mFilesTable->setEditTriggers(QAbstractItemView::NoEditTriggers); - mFilesTable->setAlternatingRowColors(true); - mFilesTable->setVerticalScrollMode(QAbstractItemView::ScrollPerItem); - mFilesTable->horizontalHeader()->setStretchLastSection(true); - mFilesTable->horizontalHeader()->hide(); - - mFilesTable->verticalHeader()->setDefaultSectionSize(height); - mFilesTable->verticalHeader()->setResizeMode(QHeaderView::Fixed); - mFilesTable->setColumnHidden(1, true); - mFilesTable->setColumnHidden(2, true); - mFilesTable->setColumnHidden(3, true); - mFilesTable->setColumnHidden(4, true); - mFilesTable->setColumnHidden(5, true); - mFilesTable->setColumnHidden(6, true); - mFilesTable->setColumnHidden(7, true); - mFilesTable->setColumnHidden(8, true); - - QVBoxLayout *pageLayout = new QVBoxLayout(this); - - pageLayout->addWidget(filterToolBar); - pageLayout->addWidget(mFilesTable); - - connect(mFilesTable, SIGNAL(doubleClicked(QModelIndex)), this, SLOT(setCheckState(QModelIndex))); - - connect(mFilesModel, SIGNAL(checkedItemsChanged(QStringList,QStringList)), mFilesModel, SLOT(slotcheckedItemsChanged(QStringList,QStringList))); - - connect(filterLineEdit, SIGNAL(textChanged(QString)), this, SLOT(filterChanged(QString))); - - connect(mFilesTable, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(showContextMenu(QPoint))); - - createActions(); -} - -void DataFilesList::createActions() -{ - // Refresh the plugins - QAction *refreshAction = new QAction(tr("Refresh"), this); - refreshAction->setShortcut(QKeySequence(tr("F5"))); - connect(refreshAction, SIGNAL(triggered()), this, SLOT(refresh())); - - // Context menu actions - mCheckAction = new QAction(tr("Check selected"), this); - connect(mCheckAction, SIGNAL(triggered()), this, SLOT(check())); - - mUncheckAction = new QAction(tr("Uncheck selected"), this); - connect(mUncheckAction, SIGNAL(triggered()), this, SLOT(uncheck())); - - // Context menu for the plugins table - mContextMenu = new QMenu(this); - - mContextMenu->addAction(mCheckAction); - mContextMenu->addAction(mUncheckAction); - -} - -bool DataFilesList::setupDataFiles(Files::PathContainer dataDirs, const QString encoding) -{ - // Set the charset for reading the esm/esp files - if (!encoding.isEmpty() && encoding != QLatin1String("win1252")) { - mFilesModel->setEncoding(encoding); - } - - // Add the paths to the respective models - for (Files::PathContainer::iterator it = dataDirs.begin(); it != dataDirs.end(); ++it) { - QString path = QString::fromStdString(it->string()); - path.remove(QChar('\"')); - mFilesModel->addFiles(path); - } - - mFilesModel->sort(0); -// mMastersTable->sortByColumn(3, Qt::AscendingOrder); -// mPluginsTable->sortByColumn(3, Qt::AscendingOrder); - - return true; -} - -void DataFilesList::selectedFiles(std::vector& paths) -{ - QStringList pluginPaths = mFilesModel->checkedItemsPaths(); - foreach (const QString &path, pluginPaths) - { - paths.push_back(path.toStdString()); - } -} - -void DataFilesList::check() -{ - // Check the current selection - if (!mFilesTable->selectionModel()->hasSelection()) { - return; - } - - QModelIndexList indexes = mFilesTable->selectionModel()->selectedIndexes(); - - //sort selection ascending because selectedIndexes returns an unsorted list - //qSort(indexes.begin(), indexes.end(), rowSmallerThan); - - foreach (const QModelIndex &index, indexes) { - if (!index.isValid()) - return; - - mFilesModel->setCheckState(index, Qt::Checked); - } -} - -void DataFilesList::uncheck() -{ - // uncheck the current selection - if (!mFilesTable->selectionModel()->hasSelection()) { - return; - } - - QModelIndexList indexes = mFilesTable->selectionModel()->selectedIndexes(); - - //sort selection ascending because selectedIndexes returns an unsorted list - //qSort(indexes.begin(), indexes.end(), rowSmallerThan); - - foreach (const QModelIndex &index, indexes) { - if (!index.isValid()) - return; - - mFilesModel->setCheckState(index, Qt::Unchecked); - } -} - -void DataFilesList::refresh() -{ - mFilesModel->sort(0); - - - // Refresh the plugins table - mFilesTable->scrollToTop(); -} - - -void DataFilesList::setCheckState(QModelIndex index) -{ - if (!index.isValid()) - return; - - QObject *object = QObject::sender(); - - // Not a signal-slot call - if (!object) - return; - - if (object->objectName() == QLatin1String("PluginsTable")) { - QModelIndex sourceIndex = mFilesProxyModel->mapToSource(index); - - (mFilesModel->checkState(sourceIndex) == Qt::Checked) - ? mFilesModel->setCheckState(sourceIndex, Qt::Unchecked) - : mFilesModel->setCheckState(sourceIndex, Qt::Checked); - } - - return; - -} - -void DataFilesList::uncheckAll() -{ - mFilesModel->uncheckAll(); -} - -void DataFilesList::filterChanged(const QString filter) -{ - QRegExp regExp(filter, Qt::CaseInsensitive, QRegExp::FixedString); - mFilesProxyModel->setFilterRegExp(regExp); -} - -void DataFilesList::showContextMenu(const QPoint &point) -{ - // Make sure there are plugins in the view - if (!mFilesTable->selectionModel()->hasSelection()) { - return; - } - - QPoint globalPos = mFilesTable->mapToGlobal(point); - - QModelIndexList indexes = mFilesTable->selectionModel()->selectedIndexes(); - - // Show the check/uncheck actions depending on the state of the selected items - mUncheckAction->setEnabled(false); - mCheckAction->setEnabled(false); - - foreach (const QModelIndex &index, indexes) { - if (!index.isValid()) - return; - - (mFilesModel->checkState(index) == Qt::Checked) - ? mUncheckAction->setEnabled(true) - : mCheckAction->setEnabled(true); - } - - // Show menu - mContextMenu->exec(globalPos); -} - -void DataFilesList::setCheckState(const QString& element, Qt::CheckState state) -{ - EsmFile *file = mFilesModel->findItem(element); - if (file) - { - mFilesModel->setCheckState(mFilesModel->indexFromItem(file), Qt::Checked); - } -} - -QStringList DataFilesList::checkedFiles() -{ - return mFilesModel->checkedItems(); -} diff --git a/components/fileorderlist/datafileslist.hpp b/components/fileorderlist/datafileslist.hpp deleted file mode 100644 index 69a20393c..000000000 --- a/components/fileorderlist/datafileslist.hpp +++ /dev/null @@ -1,75 +0,0 @@ -#ifndef DATAFILESLIST_H -#define DATAFILESLIST_H - -#include -#include -#include - - -class QTableView; -class QSortFilterProxyModel; -class QSettings; -class QAction; -class QToolBar; -class QMenu; -class ProfilesComboBox; -class DataFilesModel; - -class TextInputDialog; - -namespace Files { struct ConfigurationManager; } - -class DataFilesList : public QWidget -{ - Q_OBJECT - -public: - DataFilesList(Files::ConfigurationManager& cfg, QWidget *parent = 0); - - 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); - - // Action slots -// void moveUp(); -// void moveDown(); -// void moveTop(); -// void moveBottom(); - void check(); - void uncheck(); - void refresh(); - -private: - DataFilesModel *mFilesModel; - - QSortFilterProxyModel *mFilesProxyModel; - - QTableView *mFilesTable; - - QMenu *mContextMenu; - -// QAction *mMoveUpAction; -// QAction *mMoveDownAction; -// QAction *mMoveTopAction; -// QAction *mMoveBottomAction; - QAction *mCheckAction; - QAction *mUncheckAction; - - Files::ConfigurationManager &mCfgMgr; - -// const QStringList checkedPlugins(); -// const QStringList selectedMasters(); - - void createActions(); -}; - -#endif diff --git a/components/fileorderlist/model/datafilesmodel.cpp b/components/fileorderlist/model/datafilesmodel.cpp index 4e9b69dc2..b33e2e12a 100644 --- a/components/fileorderlist/model/datafilesmodel.cpp +++ b/components/fileorderlist/model/datafilesmodel.cpp @@ -212,6 +212,7 @@ bool DataFilesModel::setData(const QModelIndex &index, const QVariant &value, in QModelIndex lastIndex = indexFromItem(mFiles.last()); emit dataChanged(firstIndex, lastIndex); + emit checkedItemsChanged(checkedItems()); return true; } diff --git a/components/fileorderlist/model/datafilesmodel.hpp b/components/fileorderlist/model/datafilesmodel.hpp index 0e5008abe..0a07a536f 100644 --- a/components/fileorderlist/model/datafilesmodel.hpp +++ b/components/fileorderlist/model/datafilesmodel.hpp @@ -48,6 +48,9 @@ public: QModelIndex indexFromItem(EsmFile *item) const; EsmFile* findItem(const QString &name); EsmFile* item(int row) const; + +signals: + void checkedItemsChanged(const QStringList &items); private: bool canBeChecked(EsmFile *file) const; diff --git a/apps/launcher/model/pluginsproxymodel.cpp b/components/fileorderlist/model/pluginsproxymodel.cpp similarity index 100% rename from apps/launcher/model/pluginsproxymodel.cpp rename to components/fileorderlist/model/pluginsproxymodel.cpp diff --git a/apps/launcher/model/pluginsproxymodel.hpp b/components/fileorderlist/model/pluginsproxymodel.hpp similarity index 100% rename from apps/launcher/model/pluginsproxymodel.hpp rename to components/fileorderlist/model/pluginsproxymodel.hpp diff --git a/apps/launcher/resources/icons/tango/document-new.png b/files/launcher/icons/tango/document-new.png similarity index 100% rename from apps/launcher/resources/icons/tango/document-new.png rename to files/launcher/icons/tango/document-new.png diff --git a/apps/launcher/resources/icons/tango/edit-copy.png b/files/launcher/icons/tango/edit-copy.png similarity index 100% rename from apps/launcher/resources/icons/tango/edit-copy.png rename to files/launcher/icons/tango/edit-copy.png diff --git a/apps/launcher/resources/icons/tango/edit-delete.png b/files/launcher/icons/tango/edit-delete.png similarity index 100% rename from apps/launcher/resources/icons/tango/edit-delete.png rename to files/launcher/icons/tango/edit-delete.png diff --git a/apps/launcher/resources/icons/tango/go-bottom.png b/files/launcher/icons/tango/go-bottom.png similarity index 100% rename from apps/launcher/resources/icons/tango/go-bottom.png rename to files/launcher/icons/tango/go-bottom.png diff --git a/apps/launcher/resources/icons/tango/go-down.png b/files/launcher/icons/tango/go-down.png similarity index 100% rename from apps/launcher/resources/icons/tango/go-down.png rename to files/launcher/icons/tango/go-down.png diff --git a/apps/launcher/resources/icons/tango/go-top.png b/files/launcher/icons/tango/go-top.png similarity index 100% rename from apps/launcher/resources/icons/tango/go-top.png rename to files/launcher/icons/tango/go-top.png diff --git a/apps/launcher/resources/icons/tango/go-up.png b/files/launcher/icons/tango/go-up.png similarity index 100% rename from apps/launcher/resources/icons/tango/go-up.png rename to files/launcher/icons/tango/go-up.png diff --git a/apps/launcher/resources/icons/tango/index.theme b/files/launcher/icons/tango/index.theme similarity index 100% rename from apps/launcher/resources/icons/tango/index.theme rename to files/launcher/icons/tango/index.theme diff --git a/apps/launcher/resources/icons/tango/video-display.png b/files/launcher/icons/tango/video-display.png similarity index 100% rename from apps/launcher/resources/icons/tango/video-display.png rename to files/launcher/icons/tango/video-display.png diff --git a/apps/launcher/resources/images/clear.png b/files/launcher/images/clear.png similarity index 100% rename from apps/launcher/resources/images/clear.png rename to files/launcher/images/clear.png diff --git a/apps/launcher/resources/images/down.png b/files/launcher/images/down.png similarity index 100% rename from apps/launcher/resources/images/down.png rename to files/launcher/images/down.png diff --git a/apps/launcher/resources/images/openmw-header.png b/files/launcher/images/openmw-header.png similarity index 100% rename from apps/launcher/resources/images/openmw-header.png rename to files/launcher/images/openmw-header.png diff --git a/apps/launcher/resources/images/openmw-plugin.png b/files/launcher/images/openmw-plugin.png similarity index 100% rename from apps/launcher/resources/images/openmw-plugin.png rename to files/launcher/images/openmw-plugin.png diff --git a/apps/launcher/resources/images/openmw.ico b/files/launcher/images/openmw.ico similarity index 100% rename from apps/launcher/resources/images/openmw.ico rename to files/launcher/images/openmw.ico diff --git a/apps/launcher/resources/images/openmw.png b/files/launcher/images/openmw.png similarity index 100% rename from apps/launcher/resources/images/openmw.png rename to files/launcher/images/openmw.png diff --git a/apps/launcher/resources/images/playpage-background.png b/files/launcher/images/playpage-background.png similarity index 100% rename from apps/launcher/resources/images/playpage-background.png rename to files/launcher/images/playpage-background.png diff --git a/files/launcher/launcher.qrc b/files/launcher/launcher.qrc new file mode 100644 index 000000000..19b1c5a6f --- /dev/null +++ b/files/launcher/launcher.qrc @@ -0,0 +1,21 @@ + + + images/clear.png + images/down.png + images/openmw.png + images/openmw-plugin.png + images/openmw-header.png + images/playpage-background.png + + + icons/tango/index.theme + icons/tango/video-display.png + icons/tango/document-new.png + icons/tango/edit-copy.png + icons/tango/edit-delete.png + icons/tango/go-bottom.png + icons/tango/go-down.png + icons/tango/go-top.png + icons/tango/go-up.png + + diff --git a/apps/launcher/ui/datafilespage.ui b/files/ui/datafilespage.ui similarity index 98% rename from apps/launcher/ui/datafilespage.ui rename to files/ui/datafilespage.ui index 91b5475e6..044817fb4 100644 --- a/apps/launcher/ui/datafilespage.ui +++ b/files/ui/datafilespage.ui @@ -59,7 +59,7 @@ - + Current Profile: diff --git a/apps/launcher/ui/graphicspage.ui b/files/ui/graphicspage.ui similarity index 100% rename from apps/launcher/ui/graphicspage.ui rename to files/ui/graphicspage.ui diff --git a/apps/launcher/ui/mainwindow.ui b/files/ui/mainwindow.ui similarity index 100% rename from apps/launcher/ui/mainwindow.ui rename to files/ui/mainwindow.ui diff --git a/apps/launcher/ui/playpage.ui b/files/ui/playpage.ui similarity index 100% rename from apps/launcher/ui/playpage.ui rename to files/ui/playpage.ui