1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
#include "./pathselection.h"
#include "./clearlineedit.h"
#include "../misc/desktoputils.h"
#include <c++utilities/io/path.h>
#include <QCompleter>
#include <QFileDialog>
#include <QFileSystemModel>
#include <QHBoxLayout>
#include <QMenu>
#include <QPushButton>
#include <QStringBuilder>
#ifndef QT_NO_CONTEXTMENU
#include <QContextMenuEvent>
#endif
#include <functional>
#include <memory>
using namespace std;
namespace QtUtilities {
/*!
* \class PathSelection
* \brief A QLineEdit with a QPushButton next to it which allows to select
* file/directory via QFileDialog.
*/
QCompleter *PathSelection::s_completer = nullptr;
/*!
* \brief Constructs a path selection widget.
*/
PathSelection::PathSelection(QWidget *parent)
: QWidget(parent)
, m_lineEdit(new ClearLineEdit(this))
, m_button(new QPushButton(this))
, m_customDialog(nullptr)
, m_customMode(QFileDialog::Directory)
{
if (!s_completer) {
s_completer = new QCompleter;
s_completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
auto *const fileSystemModel = new QFileSystemModel(s_completer);
fileSystemModel->setRootPath(QString());
s_completer->setModel(fileSystemModel);
}
m_lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
m_lineEdit->installEventFilter(this);
m_lineEdit->setCompleter(s_completer);
m_button->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
setTexts();
auto *const layout = new QHBoxLayout(this);
layout->setSpacing(3);
layout->setContentsMargins(0, 0, 0, 0);
layout->addWidget(m_lineEdit);
layout->addWidget(m_button);
setLayout(layout);
connect(m_button, &QPushButton::clicked, this, &PathSelection::showFileDialog);
}
bool PathSelection::event(QEvent *event)
{
switch (event->type()) {
case QEvent::LanguageChange:
setTexts();
break;
default:;
}
return QWidget::event(event);
}
bool PathSelection::eventFilter(QObject *obj, QEvent *event)
{
#ifndef QT_NO_CONTEXTMENU
if (obj == m_lineEdit) {
switch (event->type()) {
case QEvent::ContextMenu: {
unique_ptr<QMenu> menu(m_lineEdit->createStandardContextMenu());
menu->addSeparator();
connect(menu->addAction(QIcon::fromTheme(QStringLiteral("document-open")), tr("Select ...")), &QAction::triggered, this,
&PathSelection::showFileDialog);
QFileInfo fileInfo(m_lineEdit->text());
if (fileInfo.exists()) {
if (fileInfo.isFile()) {
connect(menu->addAction(QIcon::fromTheme(QStringLiteral("system-run")), tr("Open")), &QAction::triggered,
bind(&openLocalFileOrDir, m_lineEdit->text()));
} else if (fileInfo.isDir()) {
connect(menu->addAction(QIcon::fromTheme(QStringLiteral("system-file-manager")), tr("Explore")), &QAction::triggered,
bind(&openLocalFileOrDir, m_lineEdit->text()));
}
}
menu->exec(static_cast<QContextMenuEvent *>(event)->globalPos());
}
return true;
default:;
}
}
#endif
return QWidget::eventFilter(obj, event);
}
void PathSelection::showFileDialog()
{
QString directory;
QFileInfo fileInfo(m_lineEdit->text());
if (fileInfo.exists()) {
if (fileInfo.isFile()) {
directory = fileInfo.absoluteDir().absolutePath();
} else {
directory = fileInfo.absolutePath();
}
}
if (m_customDialog) {
m_customDialog->setDirectory(directory);
if (m_customDialog->exec() == QFileDialog::Accepted) {
m_lineEdit->selectAll();
m_lineEdit->insert(m_customDialog->selectedFiles().join(SEARCH_PATH_SEP_CHAR));
}
} else {
QFileDialog dialog(this);
dialog.setDirectory(directory);
dialog.setFileMode(m_customMode);
if (window()) {
dialog.setWindowTitle(tr("Select path") % QStringLiteral(" - ") % window()->windowTitle());
} else {
dialog.setWindowTitle(tr("Select path"));
}
if (dialog.exec() == QFileDialog::Accepted) {
m_lineEdit->selectAll();
m_lineEdit->insert(dialog.selectedFiles().join(SEARCH_PATH_SEP_CHAR));
}
}
}
void PathSelection::setTexts()
{
m_button->setText(tr("Select ..."));
}
} // namespace QtUtilities
|