Implementing ContentSelector class in DataFilesPage

Moved AdjusterWidget / FileWidget to ContentSelectorView
This commit is contained in:
graffy76 2013-10-01 21:29:45 -05:00
parent 24b167b755
commit 00c78a4aa1
18 changed files with 316 additions and 359 deletions

View file

@ -84,6 +84,7 @@ if(QT_QTGUI_LIBRARY AND QT_QTCORE_LIBRARY)
model/naturalsort model/contentmodel
view/profilescombobox view/comboboxlineedit
view/lineedit view/contentselector
view/filewidget view/adjusterwidget
)
include(${QT_USE_FILE})

View file

@ -0,0 +1,95 @@
#include "adjusterwidget.hpp"
#include <stdexcept>
#include <string>
#include <boost/filesystem.hpp>
#include <QHBoxLayout>
#include <QLabel>
#include <QStyle>
CSVDoc::AdjusterWidget::AdjusterWidget (QWidget *parent)
: QWidget (parent), mValid (false)
{
QHBoxLayout *layout = new QHBoxLayout (this);
mIcon = new QLabel (this);
layout->addWidget (mIcon, 0);
mMessage = new QLabel (this);
mMessage->setWordWrap (true);
mMessage->setSizePolicy (QSizePolicy (QSizePolicy::Minimum, QSizePolicy::Minimum));
layout->addWidget (mMessage, 1);
setName ("", false);
setLayout (layout);
}
void CSVDoc::AdjusterWidget::setLocalData (const boost::filesystem::path& localData)
{
mLocalData = localData;
}
boost::filesystem::path CSVDoc::AdjusterWidget::getPath() const
{
if (!mValid)
throw std::logic_error ("invalid content file path");
return mResultPath;
}
bool CSVDoc::AdjusterWidget::isValid() const
{
return mValid;
}
void CSVDoc::AdjusterWidget::setName (const QString& name, bool addon)
{
QString message;
if (name.isEmpty())
{
mValid = false;
message = "No name.";
}
else
{
boost::filesystem::path path (name.toUtf8().data());
path.replace_extension (addon ? ".omwaddon" : ".omwgame");
if (path.parent_path().string()==mLocalData.string())
{
// path already points to the local data directory
message = QString::fromUtf8 (("Will be saved as: " + path.native()).c_str());
mResultPath = path;
mValid = true;
}
else
{
// path points somewhere else or is a leaf name.
path = mLocalData / path.filename();
message = QString::fromUtf8 (("Will be saved as: " + path.native()).c_str());
mResultPath = path;
mValid = true;
if (boost::filesystem::exists (path))
{
/// \todo add an user setting to make this an error.
message += "<p>But a file with the same name already exists. If you continue, it will be overwritten.";
}
}
}
mMessage->setText (message);
mIcon->setPixmap (style()->standardIcon (
mValid ? QStyle::SP_MessageBoxInformation : QStyle::SP_MessageBoxWarning).
pixmap (QSize (16, 16)));
emit stateChanged (mValid);
}

View file

@ -0,0 +1,43 @@
#ifndef CSV_DOC_ADJUSTERWIDGET_H
#define CSV_DOC_ADJUSTERWIDGET_H
#include <boost/filesystem/path.hpp>
#include <QWidget>
class QLabel;
namespace CSVDoc
{
class AdjusterWidget : public QWidget
{
Q_OBJECT
boost::filesystem::path mLocalData;
QLabel *mMessage;
QLabel *mIcon;
bool mValid;
boost::filesystem::path mResultPath;
public:
AdjusterWidget (QWidget *parent = 0);
void setLocalData (const boost::filesystem::path& localData);
bool isValid() const;
boost::filesystem::path getPath() const;
///< This function must not be called if there is no valid path.
public slots:
void setName (const QString& name, bool addon);
signals:
void stateChanged (bool valid);
};
}
#endif

View file

@ -1,7 +1,7 @@
#include "contentselector.hpp"
#include "../model/contentmodel.hpp"
#include "../model/esmfile.hpp"
#include "lineedit.hpp"
#include <QSortFilterProxyModel>
@ -9,10 +9,11 @@
#include <QMenu>
#include <QContextMenuEvent>
#include <QGridLayout>
#include <QMessageBox>
#include <assert.h>
#include "../../../apps/opencs/view/doc/filewidget.hpp"
#include "../../../apps/opencs/view/doc/adjusterwidget.hpp"
#include "filewidget.hpp"
#include "adjusterwidget.hpp"
ContentSelectorView::ContentSelector *ContentSelectorView::ContentSelector::mInstance = 0;
QStringList ContentSelectorView::ContentSelector::mFilePaths;
@ -25,6 +26,7 @@ void ContentSelectorView::ContentSelector::configure(QWidget *subject, unsigned
ContentSelectorView::ContentSelector& ContentSelectorView::ContentSelector::instance()
{
assert(mInstance);
return *mInstance;
}
@ -33,6 +35,7 @@ ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent, unsigned
QWidget(parent), mFlags (flags),
mAdjusterWidget (0), mFileWidget (0)
{
ui.setupUi (this);
parent->setLayout(new QGridLayout());
@ -41,15 +44,23 @@ ContentSelectorView::ContentSelector::ContentSelector(QWidget *parent, unsigned
buildContentModel();
buildGameFileView();
buildAddonView();
buildProfilesView();
buildNewAddonView();
buildLoadAddonView();
buildProfilesView();
/*
//mContentModel->sort(3); // Sort by date accessed
*/
}
QString ContentSelectorView::ContentSelector::getNewProfileName()
{
// 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)));
return "";
}
bool ContentSelectorView::ContentSelector::isFlagged(SelectorFlags flag) const
{
@ -123,8 +134,17 @@ void ContentSelectorView::ContentSelector::buildProfilesView()
return;
}
ui.profilesComboBox->setPlaceholderText(QString("Select a profile..."));
connect(ui.profilesComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int)));
// Add the actions to the toolbuttons
ui.newProfileButton->setDefaultAction (ui.newProfileAction);
ui.deleteProfileButton->setDefaultAction (ui.deleteProfileAction);
ui.profilesComboBox->addItem ("Default");
ui.profilesComboBox->setPlaceholderText (QString("Select a profile..."));
connect (ui.profilesComboBox, SIGNAL (currentIndexChanged(int)), this, SLOT(slotCurrentProfileIndexChanged(int)));
connect (ui.profilesComboBox, SIGNAL (profileRenamed(QString,QString)), this, SIGNAL(signalProfileRenamed(QString,QString)));
connect (ui.profilesComboBox, SIGNAL (profileChanged(QString,QString)), this, SIGNAL(signalProfileChanged(QString,QString)));
connect (ui.profilesComboBox, SIGNAL (signalProfileTextChanged(QString)), this, SLOT (slotProfileTextChanged (QString)));
}
void ContentSelectorView::ContentSelector::buildLoadAddonView()
@ -136,7 +156,6 @@ void ContentSelectorView::ContentSelector::buildLoadAddonView()
}
ui.projectCreateButton->setVisible (false);
// ui.projectButtonBox->setStandardButtons(QDialogButtonBox::Open | QDialogButtonBox::Cancel);
ui.projectGroupBox->setTitle ("");
connect(ui.projectButtonBox, SIGNAL(accepted()), this, SIGNAL(accepted()));
@ -172,6 +191,17 @@ void ContentSelectorView::ContentSelector::buildNewAddonView()
connect(ui.projectButtonBox, SIGNAL(rejected()), this, SIGNAL(rejected()));
}
void ContentSelectorView::ContentSelector::setCheckStates(const QStringList &list)
{
if (list.isEmpty())
return;
mContentModel->uncheckAll();
foreach (const QString &file, list)
mContentModel->setCheckState(file, Qt::Checked);
}
QString ContentSelectorView::ContentSelector::filename() const
{
QString filepath = "";
@ -182,7 +212,7 @@ QString ContentSelectorView::ContentSelector::filename() const
return filepath;
}
QStringList ContentSelectorView::ContentSelector::selectedFiles() const
QStringList ContentSelectorView::ContentSelector::selectedFilePaths() const
{
QStringList filePaths;
@ -195,6 +225,15 @@ QStringList ContentSelectorView::ContentSelector::selectedFiles() const
return filePaths;
}
ContentSelectorModel::ContentFileList
ContentSelectorView::ContentSelector::selectedFiles() const
{
if (mContentModel)
return mContentModel->checkedItems();
return ContentSelectorModel::ContentFileList();
}
void ContentSelectorView::ContentSelector::addFiles(const QString &path)
{
@ -209,6 +248,55 @@ void ContentSelectorView::ContentSelector::addFiles(const QString &path)
}
}
void ContentSelectorView::ContentSelector::removeProfile(const QString &item)
{
int idx = ui.profilesComboBox->findText(item);
if (idx != -1)
ui.profilesComboBox->removeItem(idx);
}
int ContentSelectorView::ContentSelector::getProfileIndex ( const QString &item) const
{
return ui.profilesComboBox->findText (item);
}
void ContentSelectorView::ContentSelector::setProfileIndex(int index)
{
if (index >=0 && index < ui.profilesComboBox->count())
ui.profilesComboBox->setCurrentIndex(index);
}
void ContentSelectorView::ContentSelector::addProfile (const QString &item, bool setAsCurrent)
{
if (item.isEmpty())
return;
if (ui.profilesComboBox->findText(item) == -1)
ui.profilesComboBox->addItem(item);
if (setAsCurrent)
ui.profilesComboBox->setCurrentIndex(ui.profilesComboBox->findText(item));
enableProfilesComboBox();
}
QString ContentSelectorView::ContentSelector::getProfileText() const
{
return ui.profilesComboBox->currentText();
}
void ContentSelectorView::ContentSelector::enableProfilesComboBox()
{
if (!ui.profilesComboBox->isEnabled())
ui.profilesComboBox->setEnabled(true);
if (!ui.deleteProfileAction->isEnabled())
ui.deleteProfileAction->setEnabled(true);
ui.projectButtonBox->button(QDialogButtonBox::Open)->setEnabled (true);
}
QStringList ContentSelectorView::ContentSelector::checkedItemsPaths()
{
QStringList itemPaths;
@ -221,6 +309,12 @@ QStringList ContentSelectorView::ContentSelector::checkedItemsPaths()
void ContentSelectorView::ContentSelector::slotCurrentProfileIndexChanged(int index)
{
//don't allow deleting "Default" profile
bool success = (ui.profilesComboBox->itemText(index) == "Default");
ui.deleteProfileAction->setEnabled(success);
ui.profilesComboBox->setEditEnabled(success);
emit signalProfileChanged(index);
}
@ -247,6 +341,14 @@ void ContentSelectorView::ContentSelector::slotCurrentGameFileIndexChanged(int i
slotUpdateCreateButton(true);
}
void ContentSelectorView::ContentSelector::slotProfileTextChanged(const QString &text)
{
QPushButton *opnBtn = ui.projectButtonBox->button(QDialogButtonBox::Open);
if (opnBtn->isEnabled())
opnBtn->setEnabled (false);
}
void ContentSelectorView::ContentSelector::slotAddonTableItemClicked(const QModelIndex &index)
{
QAbstractItemModel *const model = ui.addonView->model();
@ -257,16 +359,6 @@ void ContentSelectorView::ContentSelector::slotAddonTableItemClicked(const QMode
model->setData(index, Qt::Unchecked, Qt::CheckStateRole);
}
void ContentSelectorView::ContentSelector::slotUpdateOpenButton(const QStringList &items)
{
QPushButton *openButton = ui.projectButtonBox->button(QDialogButtonBox::Open);
if (!openButton)
return;
openButton->setEnabled(!items.isEmpty());
}
void ContentSelectorView::ContentSelector::slotUpdateCreateButton(bool)
{
//enable only if a game file is selected and the adjuster widget is non-empty
@ -278,3 +370,44 @@ void ContentSelectorView::ContentSelector::slotUpdateCreateButton(bool)
ui.projectCreateButton->setEnabled(validGameFile && validFilename);
}
void ContentSelectorView::ContentSelector::on_newProfileAction_triggered()
{
emit signalProfileAdded();
}
void ContentSelectorView::ContentSelector::on_deleteProfileAction_triggered()
{
QString profile = ui.profilesComboBox->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 <b>%0</b>?").arg(profile));
QAbstractButton *deleteButton =
msgBox.addButton(tr("Delete"), QMessageBox::ActionRole);
msgBox.exec();
if (msgBox.clickedButton() != deleteButton)
return;
// Remove the profile from the combobox
ui.profilesComboBox->removeItem(ui.profilesComboBox->findText(profile));
//signal for removal from model
emit signalProfileDeleted (profile);
}
/*
void ContentSelectorView::ContentSelector::slotUpdateOkButton(const QString &text)
{
bool success = (ui.profilesComboBox->findText(text) == -1);
mNewDialog->setOkButtonEnabled(success);
}*/

View file

@ -4,10 +4,10 @@
#include <QDialog>
#include "ui_datafilespage.h"
namespace ContentSelectorModel { class ContentModel; }
#include "../model/contentmodel.hpp"
class QSortFilterProxyModel;
class TextInputDialog;
namespace CSVDoc
{
@ -36,6 +36,8 @@ namespace ContentSelectorView
CSVDoc::FileWidget *mFileWidget;
CSVDoc::AdjusterWidget *mAdjusterWidget;
TextInputDialog *mNewDialog;
protected:
ContentSelectorModel::ContentModel *mContentModel;
@ -43,19 +45,28 @@ namespace ContentSelectorView
QSortFilterProxyModel *mAddonProxyModel;
public:
explicit ContentSelector(QWidget *parent = 0, unsigned char flags = Flag_Content);
static void configure(QWidget *subject, unsigned char flags = Flag_Content);
static ContentSelector &instance();
static void addFiles(const QString &path);
void setCheckState(QModelIndex index, QSortFilterProxyModel *model);
void setCheckStates (const QStringList &list);
QStringList checkedItemsPaths();
ContentSelectorModel::ContentFileList *CheckedItems();
QString filename() const;
QStringList selectedFiles() const;
ContentSelectorModel::ContentFileList selectedFiles() const;
QStringList selectedFilePaths() const;
void addProfile (const QString &item, bool setAsCurrent = false);
void removeProfile (const QString &item);
int getProfileIndex (const QString &item) const;
void setProfileIndex (int index);
QString getProfileText() const;
private:
explicit ContentSelector(QWidget *parent = 0, unsigned char flags = Flag_Content);
Ui::DataFilesPage ui;
void buildContentModel();
@ -66,6 +77,8 @@ namespace ContentSelectorView
void buildLoadAddonView();
bool isFlagged(SelectorFlags flag) const;
QString getNewProfileName();
void enableProfilesComboBox();
signals:
void accepted();
@ -76,14 +89,24 @@ namespace ContentSelectorView
void signalCreateButtonClicked();
void signalProfileRenamed(QString,QString);
void signalProfileChanged(QString,QString);
void signalProfileDeleted(QString);
void signalProfileAdded();
private slots:
void slotProfileTextChanged (const QString &text);
void slotCurrentProfileIndexChanged(int index);
void slotCurrentGameFileIndexChanged(int index);
void slotAddonTableItemClicked(const QModelIndex &index);
void slotUpdateCreateButton (bool);
void slotUpdateOpenButton(const QStringList &items);
// void slotUpdateOpenButton(const QStringList &items);
// Action slots
void on_newProfileAction_triggered();
void on_deleteProfileAction_triggered();
};
}

View file

@ -0,0 +1,58 @@
#include "filewidget.hpp"
#include <QHBoxLayout>
#include <QLineEdit>
#include <QLabel>
#include <QRegExpValidator>
#include <QRegExp>
QString CSVDoc::FileWidget::getExtension() const
{
return mAddon ? ".omwaddon" : ".omwgame";
}
CSVDoc::FileWidget::FileWidget (QWidget *parent) : QWidget (parent), mAddon (false)
{
QHBoxLayout *layout = new QHBoxLayout (this);
mInput = new QLineEdit (this);
mInput->setValidator (new QRegExpValidator(QRegExp("^[a-zA-Z0-9\\s]*$")));
layout->addWidget (mInput, 1);
mType = new QLabel (this);
layout ->addWidget (mType);
connect (mInput, SIGNAL (textChanged (const QString&)), this, SLOT (textChanged (const QString&)));
setLayout (layout);
}
void CSVDoc::FileWidget::setType (bool addon)
{
mAddon = addon;
mType->setText (getExtension());
}
QString CSVDoc::FileWidget::getName() const
{
QString text = mInput->text();
if (text.isEmpty())
return "";
return text + getExtension();
}
void CSVDoc::FileWidget::textChanged (const QString& text)
{
emit nameChanged (getName(), mAddon);
}
void CSVDoc::FileWidget::extensionLabelIsVisible(bool visible)
{
mType->setVisible(visible);
}

View file

@ -0,0 +1,42 @@
#ifndef CSV_DOC_FILEWIDGET_H
#define CSV_DOC_FILEWIDGET_H
#include <QWidget>
class QLabel;
class QString;
class QLineEdit;
namespace CSVDoc
{
class FileWidget : public QWidget
{
Q_OBJECT
bool mAddon;
QLineEdit *mInput;
QLabel *mType;
QString getExtension() const;
public:
FileWidget (QWidget *parent = 0);
void setType (bool addon);
QString getName() const;
void extensionLabelIsVisible(bool visible);
private slots:
void textChanged (const QString& text);
signals:
void nameChanged (const QString& file, bool addon);
};
}
#endif

View file

@ -45,6 +45,9 @@ void ContentSelectorView::ProfilesComboBox::setEditEnabled(bool editable)
connect(lineEdit(), SIGNAL(textChanged(QString)), this,
SLOT(slotTextChanged(QString)));
connect (lineEdit(), SIGNAL(textChanged(QString)), this,
SIGNAL (signalProfileTextChanged (QString)));
}
void ContentSelectorView::ProfilesComboBox::slotTextChanged(const QString &text)

View file

@ -17,10 +17,12 @@ namespace ContentSelectorView
void setPlaceholderText (const QString &text);
signals:
void signalProfileTextChanged (const QString &item);
void profileChanged(const QString &previous, const QString &current);
void profileRenamed(const QString &oldName, const QString &newName);
private slots:
void slotEditingFinished();
void slotIndexChanged(int index);
void slotTextChanged(const QString &text);