Merge branch 'next' into globalmap
commit
7c22690116
@ -1,28 +0,0 @@
|
|||||||
#ifndef COMBOBOX_H
|
|
||||||
#define COMBOBOX_H
|
|
||||||
|
|
||||||
#include <QComboBox>
|
|
||||||
|
|
||||||
class ComboBox : public QComboBox
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
private:
|
|
||||||
QString oldText;
|
|
||||||
public:
|
|
||||||
ComboBox(QWidget *parent=0) : QComboBox(parent), oldText()
|
|
||||||
{
|
|
||||||
connect(this,SIGNAL(editTextChanged(const QString&)), this,
|
|
||||||
SLOT(textChangedSlot(const QString&)));
|
|
||||||
connect(this,SIGNAL(currentIndexChanged(const QString&)), this,
|
|
||||||
SLOT(textChangedSlot(const QString&)));
|
|
||||||
}
|
|
||||||
private slots:
|
|
||||||
void textChangedSlot(const QString &newText)
|
|
||||||
{
|
|
||||||
emit textChanged(oldText, newText);
|
|
||||||
oldText = newText;
|
|
||||||
}
|
|
||||||
signals:
|
|
||||||
void textChanged(const QString &oldText, const QString &newText);
|
|
||||||
};
|
|
||||||
#endif
|
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,474 @@
|
|||||||
|
#include <QDebug>
|
||||||
|
#include <QFileInfo>
|
||||||
|
#include <QDir>
|
||||||
|
|
||||||
|
#include <components/esm/esmreader.hpp>
|
||||||
|
|
||||||
|
#include "esm/esmfile.hpp"
|
||||||
|
|
||||||
|
#include "../utils/naturalsort.hpp"
|
||||||
|
|
||||||
|
#include "datafilesmodel.hpp"
|
||||||
|
|
||||||
|
DataFilesModel::DataFilesModel(QObject *parent) :
|
||||||
|
QAbstractTableModel(parent)
|
||||||
|
{
|
||||||
|
mEncoding = QString("win1252");
|
||||||
|
}
|
||||||
|
|
||||||
|
DataFilesModel::~DataFilesModel()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataFilesModel::setEncoding(const QString &encoding)
|
||||||
|
{
|
||||||
|
mEncoding = encoding;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataFilesModel::setCheckState(const QModelIndex &index, Qt::CheckState state)
|
||||||
|
{
|
||||||
|
setData(index, state, Qt::CheckStateRole);
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::CheckState DataFilesModel::checkState(const QModelIndex &index)
|
||||||
|
{
|
||||||
|
EsmFile *file = item(index.row());
|
||||||
|
return mCheckStates[file->fileName()];
|
||||||
|
}
|
||||||
|
|
||||||
|
int DataFilesModel::columnCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return parent.isValid() ? 0 : 9;
|
||||||
|
}
|
||||||
|
|
||||||
|
int DataFilesModel::rowCount(const QModelIndex &parent) const
|
||||||
|
{
|
||||||
|
return parent.isValid() ? 0 : mFiles.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
bool DataFilesModel::moveRow(int oldrow, int row, const QModelIndex &parent)
|
||||||
|
{
|
||||||
|
if (oldrow < 0 || row < 0 || oldrow == row)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
emit layoutAboutToBeChanged();
|
||||||
|
//emit beginMoveRows(parent, oldrow, oldrow, parent, row);
|
||||||
|
mFiles.swap(oldrow, row);
|
||||||
|
//emit endInsertRows();
|
||||||
|
emit layoutChanged();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant DataFilesModel::data(const QModelIndex &index, int role) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
EsmFile *file = item(index.row());
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
const int column = index.column();
|
||||||
|
|
||||||
|
switch (role) {
|
||||||
|
case Qt::DisplayRole: {
|
||||||
|
|
||||||
|
switch (column) {
|
||||||
|
case 0:
|
||||||
|
return file->fileName();
|
||||||
|
case 1:
|
||||||
|
return file->author();
|
||||||
|
case 2:
|
||||||
|
return QString("%1 kB").arg(int((file->size() + 1023) / 1024));
|
||||||
|
case 3:
|
||||||
|
//return file->modified().toString(Qt::TextDate);
|
||||||
|
return file->modified().toString(Qt::ISODate);
|
||||||
|
case 4:
|
||||||
|
return file->accessed().toString(Qt::TextDate);
|
||||||
|
case 5:
|
||||||
|
return file->version();
|
||||||
|
case 6:
|
||||||
|
return file->path();
|
||||||
|
case 7:
|
||||||
|
return file->masters().join(", ");
|
||||||
|
case 8:
|
||||||
|
return file->description();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case Qt::TextAlignmentRole: {
|
||||||
|
switch (column) {
|
||||||
|
case 0:
|
||||||
|
case 1:
|
||||||
|
return Qt::AlignLeft + Qt::AlignVCenter;
|
||||||
|
case 2:
|
||||||
|
case 3:
|
||||||
|
case 4:
|
||||||
|
case 5:
|
||||||
|
return Qt::AlignRight + Qt::AlignVCenter;
|
||||||
|
default:
|
||||||
|
return Qt::AlignLeft + Qt::AlignVCenter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
case Qt::CheckStateRole: {
|
||||||
|
if (column != 0)
|
||||||
|
return QVariant();
|
||||||
|
return mCheckStates[file->fileName()];
|
||||||
|
}
|
||||||
|
case Qt::ToolTipRole:
|
||||||
|
{
|
||||||
|
if (column != 0)
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
if (file->version() == 0.0f)
|
||||||
|
return QVariant(); // Data not set
|
||||||
|
|
||||||
|
QString tooltip =
|
||||||
|
QString("<b>Author:</b> %1<br/> \
|
||||||
|
<b>Version:</b> %2<br/> \
|
||||||
|
<br/><b>Description:</b><br/>%3<br/> \
|
||||||
|
<br/><b>Dependencies: </b>%4<br/>")
|
||||||
|
.arg(file->author())
|
||||||
|
.arg(QString::number(file->version()))
|
||||||
|
.arg(file->description())
|
||||||
|
.arg(file->masters().join(", "));
|
||||||
|
|
||||||
|
|
||||||
|
return tooltip;
|
||||||
|
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
Qt::ItemFlags DataFilesModel::flags(const QModelIndex &index) const
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return Qt::NoItemFlags;
|
||||||
|
|
||||||
|
EsmFile *file = item(index.row());
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
return Qt::NoItemFlags;
|
||||||
|
|
||||||
|
if (mAvailableFiles.contains(file->fileName())) {
|
||||||
|
if (index.column() == 0) {
|
||||||
|
return Qt::ItemIsUserCheckable | Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||||
|
} else {
|
||||||
|
return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (index.column() == 0) {
|
||||||
|
return Qt::ItemIsUserCheckable | Qt::ItemIsSelectable;
|
||||||
|
} else {
|
||||||
|
return Qt::NoItemFlags | Qt::ItemIsSelectable;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QVariant DataFilesModel::headerData(int section, Qt::Orientation orientation, int role) const
|
||||||
|
{
|
||||||
|
if (role != Qt::DisplayRole)
|
||||||
|
return QVariant();
|
||||||
|
|
||||||
|
if (orientation == Qt::Horizontal) {
|
||||||
|
switch (section) {
|
||||||
|
case 0: return tr("Name");
|
||||||
|
case 1: return tr("Author");
|
||||||
|
case 2: return tr("Size");
|
||||||
|
case 3: return tr("Modified");
|
||||||
|
case 4: return tr("Accessed");
|
||||||
|
case 5: return tr("Version");
|
||||||
|
case 6: return tr("Path");
|
||||||
|
case 7: return tr("Masters");
|
||||||
|
case 8: return tr("Description");
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Show row numbers
|
||||||
|
return ++section;
|
||||||
|
}
|
||||||
|
|
||||||
|
return QVariant();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool DataFilesModel::setData(const QModelIndex &index, const QVariant &value, int role)
|
||||||
|
{
|
||||||
|
if (!index.isValid())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (role == Qt::CheckStateRole) {
|
||||||
|
|
||||||
|
emit layoutAboutToBeChanged();
|
||||||
|
|
||||||
|
QString name = item(index.row())->fileName();
|
||||||
|
mCheckStates[name] = static_cast<Qt::CheckState>(value.toInt());
|
||||||
|
|
||||||
|
emit checkedItemsChanged(checkedItems(), uncheckedItems());
|
||||||
|
emit layoutChanged();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataFilesModel::sort(int column, Qt::SortOrder order)
|
||||||
|
{
|
||||||
|
// TODO: Make this more efficient
|
||||||
|
emit layoutAboutToBeChanged();
|
||||||
|
|
||||||
|
QList<EsmFile *> sortedFiles;
|
||||||
|
|
||||||
|
QMultiMap<QString, QString> timestamps;
|
||||||
|
|
||||||
|
foreach (EsmFile *file, mFiles)
|
||||||
|
timestamps.insert(file->modified().toString(Qt::ISODate), file->fileName());
|
||||||
|
|
||||||
|
QMapIterator<QString, QString> ti(timestamps);
|
||||||
|
|
||||||
|
while (ti.hasNext()) {
|
||||||
|
ti.next();
|
||||||
|
|
||||||
|
QModelIndex index = indexFromItem(findItem(ti.value()));
|
||||||
|
|
||||||
|
if (!index.isValid())
|
||||||
|
continue;
|
||||||
|
|
||||||
|
EsmFile *file = item(index.row());
|
||||||
|
|
||||||
|
if (!file)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
sortedFiles.append(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
mFiles.clear();
|
||||||
|
mFiles = sortedFiles;
|
||||||
|
|
||||||
|
emit layoutChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataFilesModel::addFile(EsmFile *file)
|
||||||
|
{
|
||||||
|
emit beginInsertRows(QModelIndex(), mFiles.count(), mFiles.count());
|
||||||
|
mFiles.append(file);
|
||||||
|
emit endInsertRows();
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataFilesModel::addMasters(const QString &path)
|
||||||
|
{
|
||||||
|
QDir dir(path);
|
||||||
|
dir.setNameFilters(QStringList(QLatin1String("*.esp")));
|
||||||
|
|
||||||
|
// Read the dependencies from the plugins
|
||||||
|
foreach (const QString &path, dir.entryList()) {
|
||||||
|
try {
|
||||||
|
ESM::ESMReader fileReader;
|
||||||
|
fileReader.setEncoding(mEncoding.toStdString());
|
||||||
|
fileReader.open(dir.absoluteFilePath(path).toStdString());
|
||||||
|
|
||||||
|
ESM::ESMReader::MasterList mlist = fileReader.getMasters();
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < mlist.size(); ++i) {
|
||||||
|
QString master = QString::fromStdString(mlist[i].name);
|
||||||
|
|
||||||
|
// Add the plugin to the internal dependency map
|
||||||
|
mDependencies[master].append(path);
|
||||||
|
|
||||||
|
// Don't add esps
|
||||||
|
if (master.endsWith(".esp", Qt::CaseInsensitive))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
QFileInfo info(dir.absoluteFilePath(master));
|
||||||
|
|
||||||
|
EsmFile *file = new EsmFile(master);
|
||||||
|
file->setDates(info.lastModified(), info.lastRead());
|
||||||
|
|
||||||
|
// Add the master to the table
|
||||||
|
if (findItem(master) == 0)
|
||||||
|
addFile(file);
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
} catch(std::runtime_error &e) {
|
||||||
|
// An error occurred while reading the .esp
|
||||||
|
qWarning() << "Error reading esp: " << e.what();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// See if the masters actually exist in the filesystem
|
||||||
|
dir.setNameFilters(QStringList(QLatin1String("*.esm")));
|
||||||
|
|
||||||
|
foreach (const QString &path, dir.entryList()) {
|
||||||
|
QFileInfo info(dir.absoluteFilePath(path));
|
||||||
|
|
||||||
|
if (findItem(path) == 0) {
|
||||||
|
EsmFile *file = new EsmFile(path);
|
||||||
|
file->setDates(info.lastModified(), info.lastRead());
|
||||||
|
|
||||||
|
addFile(file);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Make the master selectable
|
||||||
|
mAvailableFiles.append(path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataFilesModel::addPlugins(const QString &path)
|
||||||
|
{
|
||||||
|
QDir dir(path);
|
||||||
|
dir.setNameFilters(QStringList(QLatin1String("*.esp")));
|
||||||
|
|
||||||
|
foreach (const QString &path, dir.entryList()) {
|
||||||
|
QFileInfo info(dir.absoluteFilePath(path));
|
||||||
|
EsmFile *file = new EsmFile(path);
|
||||||
|
|
||||||
|
try {
|
||||||
|
ESM::ESMReader fileReader;
|
||||||
|
fileReader.setEncoding(mEncoding.toStdString());
|
||||||
|
fileReader.open(dir.absoluteFilePath(path).toStdString());
|
||||||
|
|
||||||
|
ESM::ESMReader::MasterList mlist = fileReader.getMasters();
|
||||||
|
QStringList masters;
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < mlist.size(); ++i) {
|
||||||
|
QString master = QString::fromStdString(mlist[i].name);
|
||||||
|
masters.append(master);
|
||||||
|
|
||||||
|
// Add the plugin to the internal dependency map
|
||||||
|
mDependencies[master].append(path);
|
||||||
|
}
|
||||||
|
|
||||||
|
file->setAuthor(QString::fromStdString(fileReader.getAuthor()));
|
||||||
|
file->setSize(info.size());
|
||||||
|
file->setDates(info.lastModified(), info.lastRead());
|
||||||
|
file->setVersion(fileReader.getFVer());
|
||||||
|
file->setPath(info.absoluteFilePath());
|
||||||
|
file->setMasters(masters);
|
||||||
|
file->setDescription(QString::fromStdString(fileReader.getDesc()));
|
||||||
|
|
||||||
|
|
||||||
|
// Put the file in the table
|
||||||
|
addFile(file);
|
||||||
|
} catch(std::runtime_error &e) {
|
||||||
|
// An error occurred while reading the .esp
|
||||||
|
qWarning() << "Error reading esp: " << e.what();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QModelIndex DataFilesModel::indexFromItem(EsmFile *item) const
|
||||||
|
{
|
||||||
|
if (item)
|
||||||
|
return createIndex(mFiles.indexOf(item), 0);
|
||||||
|
|
||||||
|
return QModelIndex();
|
||||||
|
}
|
||||||
|
|
||||||
|
EsmFile* DataFilesModel::findItem(const QString &name)
|
||||||
|
{
|
||||||
|
QList<EsmFile *>::ConstIterator it;
|
||||||
|
QList<EsmFile *>::ConstIterator itEnd = mFiles.constEnd();
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (it = mFiles.constBegin(); it != itEnd; ++it) {
|
||||||
|
EsmFile *file = item(i);
|
||||||
|
++i;
|
||||||
|
|
||||||
|
if (name == file->fileName())
|
||||||
|
return file;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Not found
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
EsmFile* DataFilesModel::item(int row) const
|
||||||
|
{
|
||||||
|
if (row >= 0 && row < mFiles.count())
|
||||||
|
return mFiles.at(row);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList DataFilesModel::checkedItems()
|
||||||
|
{
|
||||||
|
QStringList list;
|
||||||
|
|
||||||
|
QList<EsmFile *>::ConstIterator it;
|
||||||
|
QList<EsmFile *>::ConstIterator itEnd = mFiles.constEnd();
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (it = mFiles.constBegin(); it != itEnd; ++it) {
|
||||||
|
EsmFile *file = item(i);
|
||||||
|
++i;
|
||||||
|
|
||||||
|
QString name = file->fileName();
|
||||||
|
|
||||||
|
// Only add the items that are in the checked list and available
|
||||||
|
if (mCheckStates[name] == Qt::Checked && mAvailableFiles.contains(name))
|
||||||
|
list << name;
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataFilesModel::uncheckAll()
|
||||||
|
{
|
||||||
|
emit layoutAboutToBeChanged();
|
||||||
|
mCheckStates.clear();
|
||||||
|
emit layoutChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList DataFilesModel::uncheckedItems()
|
||||||
|
{
|
||||||
|
QStringList list;
|
||||||
|
QStringList checked = checkedItems();
|
||||||
|
|
||||||
|
QList<EsmFile *>::ConstIterator it;
|
||||||
|
QList<EsmFile *>::ConstIterator itEnd = mFiles.constEnd();
|
||||||
|
|
||||||
|
int i = 0;
|
||||||
|
for (it = mFiles.constBegin(); it != itEnd; ++it) {
|
||||||
|
EsmFile *file = item(i);
|
||||||
|
++i;
|
||||||
|
|
||||||
|
// Add the items that are not in the checked list
|
||||||
|
if (!checked.contains(file->fileName()))
|
||||||
|
list << file->fileName();
|
||||||
|
}
|
||||||
|
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
void DataFilesModel::slotcheckedItemsChanged(const QStringList &checkedItems, const QStringList &unCheckedItems)
|
||||||
|
{
|
||||||
|
emit layoutAboutToBeChanged();
|
||||||
|
|
||||||
|
QStringList list;
|
||||||
|
|
||||||
|
foreach (const QString &file, checkedItems) {
|
||||||
|
list << mDependencies[file];
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (const QString &file, unCheckedItems) {
|
||||||
|
foreach (const QString &remove, mDependencies[file]) {
|
||||||
|
list.removeAll(remove);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mAvailableFiles.clear();
|
||||||
|
mAvailableFiles.append(list);
|
||||||
|
|
||||||
|
emit layoutChanged();
|
||||||
|
}
|
@ -0,0 +1,71 @@
|
|||||||
|
#ifndef DATAFILESMODEL_HPP
|
||||||
|
#define DATAFILESMODEL_HPP
|
||||||
|
|
||||||
|
#include <QAbstractTableModel>
|
||||||
|
#include <QStringList>
|
||||||
|
#include <QString>
|
||||||
|
#include <QHash>
|
||||||
|
|
||||||
|
|
||||||
|
class EsmFile;
|
||||||
|
|
||||||
|
class DataFilesModel : public QAbstractTableModel
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
explicit DataFilesModel(QObject *parent = 0);
|
||||||
|
virtual ~DataFilesModel();
|
||||||
|
virtual int columnCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
virtual int rowCount(const QModelIndex &parent = QModelIndex()) const;
|
||||||
|
|
||||||
|
bool moveRow(int oldrow, int row, const QModelIndex &parent = QModelIndex());
|
||||||
|
|
||||||
|
virtual Qt::ItemFlags flags(const QModelIndex &index) const;
|
||||||
|
|
||||||
|
virtual QVariant headerData(int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const;
|
||||||
|
virtual QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const;
|
||||||
|
|
||||||
|
virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole);
|
||||||
|
void sort(int column, Qt::SortOrder order = Qt::AscendingOrder);
|
||||||
|
|
||||||
|
inline QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const
|
||||||
|
{ return QAbstractTableModel::index(row, column, parent); }
|
||||||
|
|
||||||
|
void setEncoding(const QString &encoding);
|
||||||
|
|
||||||
|
void addFile(EsmFile *file);
|
||||||
|
|
||||||
|
void addMasters(const QString &path);
|
||||||
|
void addPlugins(const QString &path);
|
||||||
|
|
||||||
|
void uncheckAll();
|
||||||
|
|
||||||
|
QStringList checkedItems();
|
||||||
|
QStringList uncheckedItems();
|
||||||
|
|
||||||
|
Qt::CheckState checkState(const QModelIndex &index);
|
||||||
|
void setCheckState(const QModelIndex &index, Qt::CheckState state);
|
||||||
|
|
||||||
|
QModelIndex indexFromItem(EsmFile *item) const;
|
||||||
|
EsmFile* findItem(const QString &name);
|
||||||
|
EsmFile* item(int row) const;
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void checkedItemsChanged(const QStringList checkedItems, const QStringList unCheckedItems);
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void slotcheckedItemsChanged(const QStringList &checkedItems, const QStringList &unCheckedItems);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QList<EsmFile *> mFiles;
|
||||||
|
QStringList mAvailableFiles;
|
||||||
|
|
||||||
|
QHash<QString, QStringList> mDependencies;
|
||||||
|
QHash<QString, Qt::CheckState> mCheckStates;
|
||||||
|
|
||||||
|
QString mEncoding;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // DATAFILESMODEL_HPP
|
@ -0,0 +1,50 @@
|
|||||||
|
#include "esmfile.hpp"
|
||||||
|
|
||||||
|
EsmFile::EsmFile(QString fileName, ModelItem *parent)
|
||||||
|
: ModelItem(parent)
|
||||||
|
{
|
||||||
|
mFileName = fileName;
|
||||||
|
mSize = 0;
|
||||||
|
mVersion = 0.0f;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EsmFile::setFileName(const QString &fileName)
|
||||||
|
{
|
||||||
|
mFileName = fileName;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EsmFile::setAuthor(const QString &author)
|
||||||
|
{
|
||||||
|
mAuthor = author;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EsmFile::setSize(const int size)
|
||||||
|
{
|
||||||
|
mSize = size;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EsmFile::setDates(const QDateTime &modified, const QDateTime &accessed)
|
||||||
|
{
|
||||||
|
mModified = modified;
|
||||||
|
mAccessed = accessed;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EsmFile::setVersion(float version)
|
||||||
|
{
|
||||||
|
mVersion = version;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EsmFile::setPath(const QString &path)
|
||||||
|
{
|
||||||
|
mPath = path;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EsmFile::setMasters(const QStringList &masters)
|
||||||
|
{
|
||||||
|
mMasters = masters;
|
||||||
|
}
|
||||||
|
|
||||||
|
void EsmFile::setDescription(const QString &description)
|
||||||
|
{
|
||||||
|
mDescription = description;
|
||||||
|
}
|
@ -0,0 +1,54 @@
|
|||||||
|
#ifndef ESMFILE_HPP
|
||||||
|
#define ESMFILE_HPP
|
||||||
|
|
||||||
|
#include <QDateTime>
|
||||||
|
#include <QStringList>
|
||||||
|
|
||||||
|
#include "../modelitem.hpp"
|
||||||
|
|
||||||
|
class EsmFile : public ModelItem
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
Q_PROPERTY(QString filename READ fileName)
|
||||||
|
|
||||||
|
public:
|
||||||
|
EsmFile(QString fileName = QString(), ModelItem *parent = 0);
|
||||||
|
|
||||||
|
~EsmFile()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void setFileName(const QString &fileName);
|
||||||
|
void setAuthor(const QString &author);
|
||||||
|
void setSize(const int size);
|
||||||
|
void setDates(const QDateTime &modified, const QDateTime &accessed);
|
||||||
|
void setVersion(const float version);
|
||||||
|
void setPath(const QString &path);
|
||||||
|
void setMasters(const QStringList &masters);
|
||||||
|
void setDescription(const QString &description);
|
||||||
|
|
||||||
|
inline QString fileName() { return mFileName; }
|
||||||
|
inline QString author() { return mAuthor; }
|
||||||
|
inline int size() { return mSize; }
|
||||||
|
inline QDateTime modified() { return mModified; }
|
||||||
|
inline QDateTime accessed() { return mAccessed; }
|
||||||
|
inline float version() { return mVersion; }
|
||||||
|
inline QString path() { return mPath; }
|
||||||
|
inline QStringList masters() { return mMasters; }
|
||||||
|
inline QString description() { return mDescription; }
|
||||||
|
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString mFileName;
|
||||||
|
QString mAuthor;
|
||||||
|
int mSize;
|
||||||
|
QDateTime mModified;
|
||||||
|
QDateTime mAccessed;
|
||||||
|
float mVersion;
|
||||||
|
QString mPath;
|
||||||
|
QStringList mMasters;
|
||||||
|
QString mDescription;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
@ -0,0 +1,57 @@
|
|||||||
|
#include "modelitem.hpp"
|
||||||
|
|
||||||
|
ModelItem::ModelItem(ModelItem *parent)
|
||||||
|
: mParentItem(parent)
|
||||||
|
, QObject(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelItem::~ModelItem()
|
||||||
|
{
|
||||||
|
qDeleteAll(mChildItems);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
ModelItem *ModelItem::parent()
|
||||||
|
{
|
||||||
|
return mParentItem;
|
||||||
|
}
|
||||||
|
|
||||||
|
int ModelItem::row() const
|
||||||
|
{
|
||||||
|
if (mParentItem)
|
||||||
|
return 1;
|
||||||
|
//return mParentItem->childRow(const_cast<ModelItem*>(this));
|
||||||
|
//return mParentItem->mChildItems.indexOf(const_cast<ModelItem*>(this));
|
||||||
|
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int ModelItem::childCount() const
|
||||||
|
{
|
||||||
|
return mChildItems.count();
|
||||||
|
}
|
||||||
|
|
||||||
|
int ModelItem::childRow(ModelItem *child) const
|
||||||
|
{
|
||||||
|
Q_ASSERT(child);
|
||||||
|
|
||||||
|
return mChildItems.indexOf(child);
|
||||||
|
}
|
||||||
|
|
||||||
|
ModelItem *ModelItem::child(int row)
|
||||||
|
{
|
||||||
|
return mChildItems.value(row);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void ModelItem::appendChild(ModelItem *item)
|
||||||
|
{
|
||||||
|
mChildItems.append(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ModelItem::removeChild(int row)
|
||||||
|
{
|
||||||
|
mChildItems.removeAt(row);
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
#ifndef MODELITEM_HPP
|
||||||
|
#define MODELITEM_HPP
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QList>
|
||||||
|
|
||||||
|
class ModelItem : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
public:
|
||||||
|
ModelItem(ModelItem *parent = 0);
|
||||||
|
~ModelItem();
|
||||||
|
|
||||||
|
ModelItem *parent();
|
||||||
|
int row() const;
|
||||||
|
|
||||||
|
int childCount() const;
|
||||||
|
int childRow(ModelItem *child) const;
|
||||||
|
ModelItem *child(int row);
|
||||||
|
|
||||||
|
void appendChild(ModelItem *child);
|
||||||
|
void removeChild(int row);
|
||||||
|
|
||||||
|
//virtual bool acceptChild(ModelItem *child);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
ModelItem *mParentItem;
|
||||||
|
QList<ModelItem*> mChildItems;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
@ -1,149 +0,0 @@
|
|||||||
#include <QMimeData>
|
|
||||||
#include <QBitArray>
|
|
||||||
|
|
||||||
#include <limits>
|
|
||||||
|
|
||||||
#include "pluginsmodel.hpp"
|
|
||||||
|
|
||||||
PluginsModel::PluginsModel(QObject *parent) : QStandardItemModel(parent)
|
|
||||||
{
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void decodeDataRecursive(QDataStream &stream, QStandardItem *item)
|
|
||||||
{
|
|
||||||
int colCount, childCount;
|
|
||||||
stream >> *item;
|
|
||||||
stream >> colCount >> childCount;
|
|
||||||
item->setColumnCount(colCount);
|
|
||||||
|
|
||||||
int childPos = childCount;
|
|
||||||
|
|
||||||
while(childPos > 0) {
|
|
||||||
childPos--;
|
|
||||||
QStandardItem *child = new QStandardItem();
|
|
||||||
decodeDataRecursive(stream, child);
|
|
||||||
item->setChild( childPos / colCount, childPos % colCount, child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool PluginsModel::dropMimeData(const QMimeData *data, Qt::DropAction action,
|
|
||||||
int row, int column, const QModelIndex &parent)
|
|
||||||
{
|
|
||||||
// Code largely based on QStandardItemModel::dropMimeData
|
|
||||||
|
|
||||||
// check if the action is supported
|
|
||||||
if (!data || !(action == Qt::CopyAction || action == Qt::MoveAction))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// check if the format is supported
|
|
||||||
QString format = QLatin1String("application/x-qstandarditemmodeldatalist");
|
|
||||||
if (!data->hasFormat(format))
|
|
||||||
return QAbstractItemModel::dropMimeData(data, action, row, column, parent);
|
|
||||||
|
|
||||||
if (row > rowCount(parent))
|
|
||||||
row = rowCount(parent);
|
|
||||||
if (row == -1)
|
|
||||||
row = rowCount(parent);
|
|
||||||
if (column == -1)
|
|
||||||
column = 0;
|
|
||||||
|
|
||||||
// decode and insert
|
|
||||||
QByteArray encoded = data->data(format);
|
|
||||||
QDataStream stream(&encoded, QIODevice::ReadOnly);
|
|
||||||
|
|
||||||
|
|
||||||
//code based on QAbstractItemModel::decodeData
|
|
||||||
// adapted to work with QStandardItem
|
|
||||||
int top = std::numeric_limits<int>::max();
|
|
||||||
int left = std::numeric_limits<int>::max();
|
|
||||||
int bottom = 0;
|
|
||||||
int right = 0;
|
|
||||||
QVector<int> rows, columns;
|
|
||||||
QVector<QStandardItem *> items;
|
|
||||||
|
|
||||||
while (!stream.atEnd()) {
|
|
||||||
int r, c;
|
|
||||||
QStandardItem *item = new QStandardItem();
|
|
||||||
stream >> r >> c;
|
|
||||||
decodeDataRecursive(stream, item);
|
|
||||||
|
|
||||||
rows.append(r);
|
|
||||||
columns.append(c);
|
|
||||||
items.append(item);
|
|
||||||
top = qMin(r, top);
|
|
||||||
left = qMin(c, left);
|
|
||||||
bottom = qMax(r, bottom);
|
|
||||||
right = qMax(c, right);
|
|
||||||
}
|
|
||||||
|
|
||||||
// insert the dragged items into the table, use a bit array to avoid overwriting items,
|
|
||||||
// since items from different tables can have the same row and column
|
|
||||||
int dragRowCount = 0;
|
|
||||||
int dragColumnCount = right - left + 1;
|
|
||||||
|
|
||||||
// Compute the number of continuous rows upon insertion and modify the rows to match
|
|
||||||
QVector<int> rowsToInsert(bottom + 1);
|
|
||||||
for (int i = 0; i < rows.count(); ++i)
|
|
||||||
rowsToInsert[rows.at(i)] = 1;
|
|
||||||
for (int i = 0; i < rowsToInsert.count(); ++i) {
|
|
||||||
if (rowsToInsert[i] == 1){
|
|
||||||
rowsToInsert[i] = dragRowCount;
|
|
||||||
++dragRowCount;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (int i = 0; i < rows.count(); ++i)
|
|
||||||
rows[i] = top + rowsToInsert[rows[i]];
|
|
||||||
|
|
||||||
QBitArray isWrittenTo(dragRowCount * dragColumnCount);
|
|
||||||
|
|
||||||
// make space in the table for the dropped data
|
|
||||||
int colCount = columnCount(parent);
|
|
||||||
if (colCount < dragColumnCount + column) {
|
|
||||||
insertColumns(colCount, dragColumnCount + column - colCount, parent);
|
|
||||||
colCount = columnCount(parent);
|
|
||||||
}
|
|
||||||
insertRows(row, dragRowCount, parent);
|
|
||||||
|
|
||||||
row = qMax(0, row);
|
|
||||||
column = qMax(0, column);
|
|
||||||
|
|
||||||
QStandardItem *parentItem = itemFromIndex (parent);
|
|
||||||
if (!parentItem)
|
|
||||||
parentItem = invisibleRootItem();
|
|
||||||
|
|
||||||
QVector<QPersistentModelIndex> newIndexes(items.size());
|
|
||||||
// set the data in the table
|
|
||||||
for (int j = 0; j < items.size(); ++j) {
|
|
||||||
int relativeRow = rows.at(j) - top;
|
|
||||||
int relativeColumn = columns.at(j) - left;
|
|
||||||
int destinationRow = relativeRow + row;
|
|
||||||
int destinationColumn = relativeColumn + column;
|
|
||||||
int flat = (relativeRow * dragColumnCount) + relativeColumn;
|
|
||||||
// if the item was already written to, or we just can't fit it in the table, create a new row
|
|
||||||
if (destinationColumn >= colCount || isWrittenTo.testBit(flat)) {
|
|
||||||
destinationColumn = qBound(column, destinationColumn, colCount - 1);
|
|
||||||
destinationRow = row + dragRowCount;
|
|
||||||
insertRows(row + dragRowCount, 1, parent);
|
|
||||||
flat = (dragRowCount * dragColumnCount) + relativeColumn;
|
|
||||||
isWrittenTo.resize(++dragRowCount * dragColumnCount);
|
|
||||||
}
|
|
||||||
if (!isWrittenTo.testBit(flat)) {
|
|
||||||
newIndexes[j] = index(destinationRow, destinationColumn, parentItem->index());
|
|
||||||
isWrittenTo.setBit(flat);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int k = 0; k < newIndexes.size(); k++) {
|
|
||||||
if (newIndexes.at(k).isValid()) {
|
|
||||||
parentItem->setChild(newIndexes.at(k).row(), newIndexes.at(k).column(), items.at(k));
|
|
||||||
} else {
|
|
||||||
delete items.at(k);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// The important part, tell the view what is dropped
|
|
||||||
emit indexesDropped(newIndexes);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
@ -1,21 +0,0 @@
|
|||||||
#ifndef PLUGINSMODEL_H
|
|
||||||
#define PLUGINSMODEL_H
|
|
||||||
|
|
||||||
#include <QStandardItemModel>
|
|
||||||
|
|
||||||
class PluginsModel : public QStandardItemModel
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
PluginsModel(QObject *parent = 0);
|
|
||||||
~PluginsModel() {};
|
|
||||||
|
|
||||||
bool dropMimeData(const QMimeData *data, Qt::DropAction action, int row, int column, const QModelIndex &parent);
|
|
||||||
|
|
||||||
signals:
|
|
||||||
void indexesDropped(QVector<QPersistentModelIndex> indexes);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,41 +0,0 @@
|
|||||||
#include <QSortFilterProxyModel>
|
|
||||||
|
|
||||||
#include "pluginsview.hpp"
|
|
||||||
|
|
||||||
PluginsView::PluginsView(QWidget *parent) : QTableView(parent)
|
|
||||||
{
|
|
||||||
setSelectionBehavior(QAbstractItemView::SelectRows);
|
|
||||||
setSelectionMode(QAbstractItemView::ExtendedSelection);
|
|
||||||
setEditTriggers(QAbstractItemView::NoEditTriggers);
|
|
||||||
setAlternatingRowColors(true);
|
|
||||||
setDragEnabled(true);
|
|
||||||
setDragDropMode(QAbstractItemView::InternalMove);
|
|
||||||
setDropIndicatorShown(true);
|
|
||||||
setDragDropOverwriteMode(false);
|
|
||||||
setContextMenuPolicy(Qt::CustomContextMenu);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void PluginsView::startDrag(Qt::DropActions supportedActions)
|
|
||||||
{
|
|
||||||
selectionModel()->select( selectionModel()->selection(),
|
|
||||||
QItemSelectionModel::Select | QItemSelectionModel::Rows );
|
|
||||||
QAbstractItemView::startDrag( supportedActions );
|
|
||||||
}
|
|
||||||
|
|
||||||
void PluginsView::setModel(QSortFilterProxyModel *model)
|
|
||||||
{
|
|
||||||
QTableView::setModel(model);
|
|
||||||
|
|
||||||
qRegisterMetaType< QVector<QPersistentModelIndex> >();
|
|
||||||
|
|
||||||
connect(model->sourceModel(), SIGNAL(indexesDropped(QVector<QPersistentModelIndex>)),
|
|
||||||
this, SLOT(selectIndexes(QVector<QPersistentModelIndex>)), Qt::QueuedConnection);
|
|
||||||
}
|
|
||||||
|
|
||||||
void PluginsView::selectIndexes( QVector<QPersistentModelIndex> aIndexes )
|
|
||||||
{
|
|
||||||
selectionModel()->clearSelection();
|
|
||||||
foreach( QPersistentModelIndex pIndex, aIndexes )
|
|
||||||
selectionModel()->select( pIndex, QItemSelectionModel::Select | QItemSelectionModel::Rows );
|
|
||||||
}
|
|
@ -1,29 +0,0 @@
|
|||||||
#ifndef PLUGINSVIEW_H
|
|
||||||
#define PLUGINSVIEW_H
|
|
||||||
|
|
||||||
#include <QTableView>
|
|
||||||
|
|
||||||
#include "pluginsmodel.hpp"
|
|
||||||
|
|
||||||
class QSortFilterProxyModel;
|
|
||||||
|
|
||||||
class PluginsView : public QTableView
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
public:
|
|
||||||
PluginsView(QWidget *parent = 0);
|
|
||||||
|
|
||||||
PluginsModel* model() const
|
|
||||||
{ return qobject_cast<PluginsModel*>(QAbstractItemView::model()); }
|
|
||||||
|
|
||||||
void startDrag(Qt::DropActions supportedActions);
|
|
||||||
void setModel(QSortFilterProxyModel *model);
|
|
||||||
|
|
||||||
public slots:
|
|
||||||
void selectIndexes(QVector<QPersistentModelIndex> aIndexes);
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
Q_DECLARE_METATYPE(QVector<QPersistentModelIndex>)
|
|
||||||
|
|
||||||
#endif
|
|
@ -0,0 +1,52 @@
|
|||||||
|
#include <QRegExpValidator>
|
||||||
|
#include <QLineEdit>
|
||||||
|
#include <QString>
|
||||||
|
|
||||||
|
#include "profilescombobox.hpp"
|
||||||
|
|
||||||
|
ProfilesComboBox::ProfilesComboBox(QWidget *parent) :
|
||||||
|
QComboBox(parent)
|
||||||
|
{
|
||||||
|
mValidator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore
|
||||||
|
|
||||||
|
setEditable(true);
|
||||||
|
setValidator(mValidator);
|
||||||
|
setCompleter(0);
|
||||||
|
|
||||||
|
connect(this, SIGNAL(currentIndexChanged(int)), this,
|
||||||
|
SLOT(slotIndexChanged(int)));
|
||||||
|
connect(lineEdit(), SIGNAL(returnPressed()), this,
|
||||||
|
SLOT(slotReturnPressed()));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProfilesComboBox::setEditEnabled(bool editable)
|
||||||
|
{
|
||||||
|
if (!editable)
|
||||||
|
return setEditable(false);
|
||||||
|
|
||||||
|
// Reset the completer and validator
|
||||||
|
setEditable(true);
|
||||||
|
setValidator(mValidator);
|
||||||
|
setCompleter(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProfilesComboBox::slotReturnPressed()
|
||||||
|
{
|
||||||
|
QString current = currentText();
|
||||||
|
QString previous = itemText(currentIndex());
|
||||||
|
|
||||||
|
if (findText(current) != -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
setItemText(currentIndex(), current);
|
||||||
|
emit(profileRenamed(previous, current));
|
||||||
|
}
|
||||||
|
|
||||||
|
void ProfilesComboBox::slotIndexChanged(int index)
|
||||||
|
{
|
||||||
|
if (index == -1)
|
||||||
|
return;
|
||||||
|
|
||||||
|
emit(profileChanged(mOldProfile, currentText()));
|
||||||
|
mOldProfile = itemText(index);
|
||||||
|
}
|
@ -0,0 +1,30 @@
|
|||||||
|
#ifndef PROFILESCOMBOBOX_HPP
|
||||||
|
#define PROFILESCOMBOBOX_HPP
|
||||||
|
|
||||||
|
#include <QComboBox>
|
||||||
|
|
||||||
|
class QString;
|
||||||
|
|
||||||
|
class QRegExpValidator;
|
||||||
|
|
||||||
|
class ProfilesComboBox : public QComboBox
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit ProfilesComboBox(QWidget *parent = 0);
|
||||||
|
void setEditEnabled(bool editable);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void profileChanged(const QString &previous, const QString ¤t);
|
||||||
|
void profileRenamed(const QString &oldName, const QString &newName);
|
||||||
|
|
||||||
|
private slots:
|
||||||
|
void slotReturnPressed();
|
||||||
|
void slotIndexChanged(int index);
|
||||||
|
|
||||||
|
private:
|
||||||
|
QString mOldProfile;
|
||||||
|
QRegExpValidator *mValidator;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PROFILESCOMBOBOX_HPP
|
@ -0,0 +1,61 @@
|
|||||||
|
#include <QDialogButtonBox>
|
||||||
|
#include <QPushButton>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QLabel>
|
||||||
|
#include <QVBoxLayout>
|
||||||
|
#include <QValidator>
|
||||||
|
|
||||||
|
#include "lineedit.hpp"
|
||||||
|
|
||||||
|
#include "textinputdialog.hpp"
|
||||||
|
|
||||||
|
TextInputDialog::TextInputDialog(const QString& title, const QString &text, QWidget *parent) :
|
||||||
|
QDialog(parent)
|
||||||
|
{
|
||||||
|
setWindowFlags(windowFlags() & ~Qt::WindowContextHelpButtonHint);
|
||||||
|
mButtonBox = new QDialogButtonBox(this);
|
||||||
|
mButtonBox->addButton(QDialogButtonBox::Ok);
|
||||||
|
mButtonBox->addButton(QDialogButtonBox::Cancel);
|
||||||
|
|
||||||
|
setMaximumHeight(height());
|
||||||
|
setOkButtonEnabled(false);
|
||||||
|
setModal(true);
|
||||||
|
|
||||||
|
// Messageboxes on mac have no title
|
||||||
|
#ifndef Q_OS_MAC
|
||||||
|
setWindowTitle(title);
|
||||||
|
#else
|
||||||
|
Q_UNUSED(title);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
QLabel *label = new QLabel(this);
|
||||||
|
label->setText(text);
|
||||||
|
|
||||||
|
// Line edit
|
||||||
|
QValidator *validator = new QRegExpValidator(QRegExp("^[a-zA-Z0-9_]*$"), this); // Alpha-numeric + underscore
|
||||||
|
mLineEdit = new LineEdit(this);
|
||||||
|
mLineEdit->setValidator(validator);
|
||||||
|
mLineEdit->setCompleter(0);
|
||||||
|
|
||||||
|
QVBoxLayout *dialogLayout = new QVBoxLayout(this);
|
||||||
|
dialogLayout->addWidget(label);
|
||||||
|
dialogLayout->addWidget(mLineEdit);
|
||||||
|
dialogLayout->addWidget(mButtonBox);
|
||||||
|
|
||||||
|
connect(mButtonBox, SIGNAL(accepted()), this, SLOT(accept()));
|
||||||
|
connect(mButtonBox, SIGNAL(rejected()), this, SLOT(reject()));
|
||||||
|
}
|
||||||
|
|
||||||
|
int TextInputDialog::exec()
|
||||||
|
{
|
||||||
|
mLineEdit->clear();
|
||||||
|
mLineEdit->setFocus();
|
||||||
|
return QDialog::exec();
|
||||||
|
}
|
||||||
|
|
||||||
|
void TextInputDialog::setOkButtonEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
|
||||||
|
QPushButton *okButton = mButtonBox->button(QDialogButtonBox::Ok);
|
||||||
|
okButton->setEnabled(enabled);
|
||||||
|
}
|
@ -0,0 +1,28 @@
|
|||||||
|
#ifndef TEXTINPUTDIALOG_HPP
|
||||||
|
#define TEXTINPUTDIALOG_HPP
|
||||||
|
|
||||||
|
#include <QDialog>
|
||||||
|
//#include "lineedit.hpp"
|
||||||
|
|
||||||
|
class QDialogButtonBox;
|
||||||
|
class LineEdit;
|
||||||
|
|
||||||
|
class TextInputDialog : public QDialog
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit TextInputDialog(const QString& title, const QString &text, QWidget *parent = 0);
|
||||||
|
inline LineEdit *lineEdit() { return mLineEdit; }
|
||||||
|
void setOkButtonEnabled(bool enabled);
|
||||||
|
|
||||||
|
LineEdit *mLineEdit;
|
||||||
|
|
||||||
|
int exec();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QDialogButtonBox *mButtonBox;
|
||||||
|
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // TEXTINPUTDIALOG_HPP
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue