Mercurial > retraceit
diff src/folderselectdialog.cpp @ 9:e3c8f61e45a9
Implement folderselection dialogs
author | Andre Heinecke <andre.heinecke@intevation.de> |
---|---|
date | Thu, 26 Mar 2015 16:30:18 +0100 |
parents | |
children | 971bd39a6116 |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/folderselectdialog.cpp Thu Mar 26 16:30:18 2015 +0100 @@ -0,0 +1,194 @@ +/* Copyright (C) 2014 by Intevation GmbH + * + * This file is Free Software under the GNU GPL (v>=2) + * and comes with ABSOLUTELY NO WARRANTY! + * See LICENSE.txt for details. + */ +#include "folderselectdialog.h" +#include "constants.h" + +#include <QSortFilterProxyModel> +#include <QStandardItemModel> +#include <QTableView> +#include <QVBoxLayout> +#include <QLineEdit> +#include <QLabel> +#include <QApplication> +#include <QStyle> +#include <QFileDialog> +#include <QStandardPaths> +#include <QPushButton> +#include <QHeaderView> +#include <QDebug> +#include <QSettings> +#include <QStringList> +#include <QStandardItem> + +FolderSelectDialog::FolderSelectDialog(const QString& startFolder, + const QString& folderPattern, + const QString& pathLabel, + QWidget * parent, + Qt::WindowFlags f) : + QDialog(parent, f), + mCurFolder(startFolder), + mFolderPattern(folderPattern), + mPathLabelString(pathLabel), + mPathLabel(NULL), + mPathLineEdit(NULL) +{ + mSortModel = new QSortFilterProxyModel(); + mModel = new QStandardItemModel(); + mShowPathSelection = !pathLabel.isEmpty(); + setupGUI(); + if (mShowPathSelection) { + mPathLabel->setText("<b>" + pathLabel + ":</b> "); + } + setFolder(mCurFolder); +} + +void FolderSelectDialog::setupGUI() { + QVBoxLayout *base = new QVBoxLayout; + QHBoxLayout *folderChangeArea = new QHBoxLayout; + + if (mShowPathSelection) { + mPathLabel = new QLabel; + folderChangeArea->addWidget(mPathLabel); + base->addLayout(folderChangeArea); + + QPushButton *folderSelect = new QPushButton(); + folderSelect->setToolTip(tr("Select folder")); + folderSelect->setIcon(QApplication::style()->standardIcon(QStyle::SP_DirIcon)); + connect(folderSelect, &QPushButton::clicked, this, + &FolderSelectDialog::changeFolderClicked); + folderChangeArea->addWidget(folderSelect); + + mPathLineEdit = new QLineEdit; + mPathLineEdit->setClearButtonEnabled(true); + connect(mPathLineEdit, &QLineEdit::textChanged, this, + &FolderSelectDialog::pathLineChanged); + folderChangeArea->addWidget(mPathLineEdit); + + mGoButton = new QPushButton(tr("Go")); + mGoButton->setEnabled(false); + folderChangeArea->addWidget(mGoButton); + connect(mGoButton, &QPushButton::clicked, this, + &FolderSelectDialog::goClicked); + } + + mFilterWidget = new FilterWidget(mSortModel); + base->addWidget(mFilterWidget); + + mView = new QTableView; + mView->setModel(mSortModel); + + mView->resizeColumnsToContents(); + mView->setSelectionBehavior(QAbstractItemView::SelectRows); + mView->setSelectionMode(QAbstractItemView::SingleSelection); + mView->setSortingEnabled(true); + mView->setEditTriggers(QAbstractItemView::NoEditTriggers); + connect(mView->selectionModel(), &QItemSelectionModel::selectionChanged, + this, &FolderSelectDialog::selectionChanged); + connect(mView, &QTableView::doubleClicked, this, + &FolderSelectDialog::wantToAccept); + + base->addWidget(mView); + + QHBoxLayout * bottomButtons = new QHBoxLayout; + base->addLayout(bottomButtons); + + mOkButton = new QPushButton(tr("Ok")); + mOkButton->setEnabled(false); + connect(mOkButton, &QPushButton::clicked, this, + &FolderSelectDialog::wantToAccept); + bottomButtons->addStretch(-1); + bottomButtons->addWidget(mOkButton); + setLayout(base); +} + +void FolderSelectDialog::selectionChanged (const QItemSelection& selected, + const QItemSelection& deselected) { + mOkButton->setEnabled(!selected.indexes().isEmpty()); +} + +void FolderSelectDialog::pathLineChanged() { + const QString path = mPathLineEdit->text(); + qDebug() << "path: " << path; + if (path.isEmpty()) { + mGoButton->setEnabled(false); + return; + } + QDir dir(path); + if (dir.exists()) { + mGoButton->setEnabled(true); + return; + } + mGoButton->setEnabled(false); +} + + +void FolderSelectDialog::goClicked() { + setFolder(mPathLineEdit->text()); + QSettings settings; + /* assuming go is only available in root folder mode */ + settings.setValue(ROOT_FOLDER_KEY, mPathLineEdit->text()); +} + +void FolderSelectDialog::setFolder(const QString& folder) { + mCurFolder = folder; + if (mPathLineEdit) { + mPathLineEdit->setText(mCurFolder); + } + + QStringList columns = mFolderPattern.split(PATTERN_SEPERATOR); + mModel->clear(); + mModel->setHorizontalHeaderLabels(columns); + QDir dir(folder); + qDebug() << "Folder set to: " << folder; + foreach (const QString & subfolder, dir.entryList(QDir::Dirs | + QDir::Readable | + QDir::NoDotAndDotDot)) { + qDebug() << "Looking at: " << subfolder; + QStringList itemData = subfolder.split(PATTERN_SEPERATOR); + if (itemData.size() != columns.size()) { + qDebug() << "Failed to parse: " << subfolder; + continue; + } + QList<QStandardItem*> items; + foreach (const QString& part, itemData) { + QStandardItem * item = new QStandardItem(part); + item->setData(dir.absoluteFilePath(subfolder)); + items.append(item); + } + mModel->appendRow(items); + } + mSortModel->setSourceModel(mModel); +} + +void FolderSelectDialog::wantToAccept() { + QItemSelectionModel *selection = mView->selectionModel(); + QModelIndexList selected = selection->selectedIndexes(); + if (selected.isEmpty()) { /* Ok should not be enabled in that case */ + return; + } + const QString folder = selected[0].data(Qt::UserRole + 1).toString(); + + emit folderSelected(folder); + accept(); +} + +void FolderSelectDialog::changeFolderClicked() +{ + const QString oldFolder = mCurFolder; + const QString startLoc = mCurFolder.isEmpty() ? + QStandardPaths::writableLocation(QStandardPaths::DocumentsLocation) : + mCurFolder; + + QString outFolder = QFileDialog::getExistingDirectory( + this, tr("Select ") + mPathLabelString, + startLoc); + if (outFolder.isEmpty()) { + /* User aborted */ + return; + } + setFolder(outFolder); +}