2016-04-09 02:32:07 +02:00
|
|
|
#include "./pathselection.h"
|
|
|
|
#include "./clearlineedit.h"
|
|
|
|
|
2016-04-16 18:35:25 +02:00
|
|
|
#include "../misc/desktoputils.h"
|
2016-04-16 00:50:31 +02:00
|
|
|
|
2016-04-16 18:35:25 +02:00
|
|
|
#include <c++utilities/io/path.h>
|
2016-04-09 02:32:07 +02:00
|
|
|
|
|
|
|
#include <QCompleter>
|
2017-05-01 03:16:25 +02:00
|
|
|
#include <QFileDialog>
|
2016-04-09 02:32:07 +02:00
|
|
|
#include <QFileSystemModel>
|
2017-05-01 03:16:25 +02:00
|
|
|
#include <QHBoxLayout>
|
|
|
|
#include <QMenu>
|
|
|
|
#include <QPushButton>
|
2016-04-09 02:32:07 +02:00
|
|
|
#include <QStringBuilder>
|
|
|
|
#ifndef QT_NO_CONTEXTMENU
|
2017-05-01 03:16:25 +02:00
|
|
|
#include <QContextMenuEvent>
|
2016-04-09 02:32:07 +02:00
|
|
|
#endif
|
|
|
|
|
2017-05-30 15:07:34 +02:00
|
|
|
#include <functional>
|
2016-04-09 02:32:07 +02:00
|
|
|
#include <memory>
|
|
|
|
|
|
|
|
using namespace std;
|
|
|
|
|
|
|
|
namespace Widgets {
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \class Widgets::PathSelection
|
2017-05-04 22:46:37 +02:00
|
|
|
* \brief A QLineEdit with a QPushButton next to it which allows to select
|
|
|
|
* file/directory via QFileDialog.
|
2016-04-09 02:32:07 +02:00
|
|
|
*/
|
|
|
|
|
|
|
|
QCompleter *PathSelection::m_completer = nullptr;
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Constructs a path selection widget.
|
|
|
|
*/
|
2017-05-01 03:16:25 +02:00
|
|
|
PathSelection::PathSelection(QWidget *parent)
|
|
|
|
: QWidget(parent)
|
|
|
|
, m_lineEdit(new ClearLineEdit(this))
|
|
|
|
, m_button(new QPushButton(this))
|
|
|
|
, m_customMode(QFileDialog::Directory)
|
|
|
|
, m_customDialog(nullptr)
|
2016-04-09 02:32:07 +02:00
|
|
|
{
|
2017-05-01 03:16:25 +02:00
|
|
|
if (!m_completer) {
|
2016-04-09 02:32:07 +02:00
|
|
|
auto *fileSystemModel = new QFileSystemModel(m_completer);
|
|
|
|
fileSystemModel->setRootPath(QString());
|
|
|
|
m_completer = new QCompleter;
|
|
|
|
m_completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
|
|
|
|
m_completer->setModel(fileSystemModel);
|
|
|
|
}
|
|
|
|
|
|
|
|
m_lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
|
|
|
|
m_lineEdit->installEventFilter(this);
|
|
|
|
m_lineEdit->setCompleter(m_completer);
|
2016-04-23 13:29:15 +02:00
|
|
|
m_button->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
2016-04-09 02:32:07 +02:00
|
|
|
m_button->setText(tr("Select ..."));
|
|
|
|
|
2016-04-23 13:29:15 +02:00
|
|
|
auto *layout = new QHBoxLayout(this);
|
2016-04-09 02:32:07 +02:00
|
|
|
layout->setSpacing(3);
|
|
|
|
layout->setMargin(0);
|
|
|
|
layout->addWidget(m_lineEdit);
|
|
|
|
layout->addWidget(m_button);
|
|
|
|
setLayout(layout);
|
|
|
|
|
|
|
|
connect(m_button, &QPushButton::clicked, this, &PathSelection::showFileDialog);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool PathSelection::eventFilter(QObject *obj, QEvent *event)
|
|
|
|
{
|
|
|
|
#ifndef QT_NO_CONTEXTMENU
|
2017-05-01 03:16:25 +02:00
|
|
|
if (obj == m_lineEdit) {
|
|
|
|
switch (event->type()) {
|
2016-04-09 02:32:07 +02:00
|
|
|
case QEvent::ContextMenu: {
|
|
|
|
unique_ptr<QMenu> menu(m_lineEdit->createStandardContextMenu());
|
|
|
|
menu->addSeparator();
|
2017-05-01 03:16:25 +02:00
|
|
|
connect(menu->addAction(QIcon::fromTheme(QStringLiteral("document-open")), tr("Select ...")), &QAction::triggered, this,
|
|
|
|
&PathSelection::showFileDialog);
|
2016-04-09 02:32:07 +02:00
|
|
|
QFileInfo fileInfo(m_lineEdit->text());
|
2017-05-01 03:16:25 +02:00
|
|
|
if (fileInfo.exists()) {
|
|
|
|
if (fileInfo.isFile()) {
|
|
|
|
connect(menu->addAction(QIcon::fromTheme(QStringLiteral("system-run")), tr("Open")), &QAction::triggered,
|
|
|
|
bind(&DesktopUtils::openLocalFileOrDir, m_lineEdit->text()));
|
|
|
|
} else if (fileInfo.isDir()) {
|
|
|
|
connect(menu->addAction(QIcon::fromTheme(QStringLiteral("system-file-manager")), tr("Explore")), &QAction::triggered,
|
|
|
|
bind(&DesktopUtils::openLocalFileOrDir, m_lineEdit->text()));
|
2016-04-09 02:32:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
menu->exec(static_cast<QContextMenuEvent *>(event)->globalPos());
|
|
|
|
}
|
|
|
|
return true;
|
2017-05-01 03:16:25 +02:00
|
|
|
default:;
|
2016-04-09 02:32:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return QWidget::eventFilter(obj, event);
|
|
|
|
}
|
|
|
|
|
|
|
|
void PathSelection::showFileDialog()
|
|
|
|
{
|
2016-04-23 13:29:15 +02:00
|
|
|
QString directory;
|
|
|
|
QFileInfo fileInfo(m_lineEdit->text());
|
2017-05-01 03:16:25 +02:00
|
|
|
if (fileInfo.exists()) {
|
|
|
|
if (fileInfo.isFile()) {
|
2016-04-23 13:29:15 +02:00
|
|
|
directory = fileInfo.absoluteDir().absolutePath();
|
|
|
|
} else {
|
|
|
|
directory = fileInfo.absolutePath();
|
|
|
|
}
|
|
|
|
}
|
2017-05-01 03:16:25 +02:00
|
|
|
if (m_customDialog) {
|
2016-04-23 13:29:15 +02:00
|
|
|
m_customDialog->setDirectory(directory);
|
2017-05-01 03:16:25 +02:00
|
|
|
if (m_customDialog->exec() == QFileDialog::Accepted) {
|
2016-04-23 13:29:15 +02:00
|
|
|
m_lineEdit->selectAll();
|
|
|
|
m_lineEdit->insert(m_customDialog->selectedFiles().join(SEARCH_PATH_SEP_CHAR));
|
2016-04-09 02:32:07 +02:00
|
|
|
}
|
|
|
|
} else {
|
|
|
|
QFileDialog dialog(this);
|
2016-04-23 13:29:15 +02:00
|
|
|
dialog.setDirectory(directory);
|
2016-04-09 02:32:07 +02:00
|
|
|
dialog.setFileMode(m_customMode);
|
2017-05-01 03:16:25 +02:00
|
|
|
if (window()) {
|
2016-04-09 02:32:07 +02:00
|
|
|
dialog.setWindowTitle(tr("Select path") % QStringLiteral(" - ") % window()->windowTitle());
|
|
|
|
} else {
|
|
|
|
dialog.setWindowTitle(tr("Select path"));
|
|
|
|
}
|
2017-05-01 03:16:25 +02:00
|
|
|
if (dialog.exec() == QFileDialog::Accepted) {
|
2016-04-23 13:29:15 +02:00
|
|
|
m_lineEdit->selectAll();
|
|
|
|
m_lineEdit->insert(dialog.selectedFiles().join(SEARCH_PATH_SEP_CHAR));
|
2016-04-09 02:32:07 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|