Qt Utilities 6.12.0
Common Qt related C++ classes and routines used by my applications such as dialogs, widgets and models
Loading...
Searching...
No Matches
pathselection.cpp
Go to the documentation of this file.
1#include "./pathselection.h"
2#include "./clearlineedit.h"
3
4#include "../misc/desktoputils.h"
5
6#include <c++utilities/io/path.h>
7
8#include <QCompleter>
9#include <QFileDialog>
10#include <QFileSystemModel>
11#include <QHBoxLayout>
12#include <QMenu>
13#include <QPushButton>
14#include <QStringBuilder>
15#ifndef QT_NO_CONTEXTMENU
16#include <QContextMenuEvent>
17#endif
18
19#include <functional>
20#include <memory>
21
22using namespace std;
23
24namespace QtUtilities {
25
32QCompleter *PathSelection::s_completer = nullptr;
33
38 : QWidget(parent)
39 , m_lineEdit(new ClearLineEdit(this))
40 , m_button(new QPushButton(this))
41 , m_customDialog(nullptr)
42 , m_customMode(QFileDialog::Directory)
43{
44 if (!s_completer) {
45 s_completer = new QCompleter;
46 s_completer->setCompletionMode(QCompleter::UnfilteredPopupCompletion);
47 auto *const fileSystemModel = new QFileSystemModel(s_completer);
48 fileSystemModel->setRootPath(QString());
49 s_completer->setModel(fileSystemModel);
50 }
51
52 m_lineEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Fixed);
53 m_lineEdit->installEventFilter(this);
54 m_lineEdit->setCompleter(s_completer);
55 m_button->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
56 m_button->setText(tr("Select ..."));
57
58 auto *const layout = new QHBoxLayout(this);
59 layout->setSpacing(3);
60 layout->setContentsMargins(0, 0, 0, 0);
61 layout->addWidget(m_lineEdit);
62 layout->addWidget(m_button);
63 setLayout(layout);
64
65 connect(m_button, &QPushButton::clicked, this, &PathSelection::showFileDialog);
66}
67
68bool PathSelection::eventFilter(QObject *obj, QEvent *event)
69{
70#ifndef QT_NO_CONTEXTMENU
71 if (obj == m_lineEdit) {
72 switch (event->type()) {
73 case QEvent::ContextMenu: {
74 unique_ptr<QMenu> menu(m_lineEdit->createStandardContextMenu());
75 menu->addSeparator();
76 connect(menu->addAction(QIcon::fromTheme(QStringLiteral("document-open")), tr("Select ...")), &QAction::triggered, this,
77 &PathSelection::showFileDialog);
78 QFileInfo fileInfo(m_lineEdit->text());
79 if (fileInfo.exists()) {
80 if (fileInfo.isFile()) {
81 connect(menu->addAction(QIcon::fromTheme(QStringLiteral("system-run")), tr("Open")), &QAction::triggered,
82 bind(&openLocalFileOrDir, m_lineEdit->text()));
83 } else if (fileInfo.isDir()) {
84 connect(menu->addAction(QIcon::fromTheme(QStringLiteral("system-file-manager")), tr("Explore")), &QAction::triggered,
85 bind(&openLocalFileOrDir, m_lineEdit->text()));
86 }
87 }
88 menu->exec(static_cast<QContextMenuEvent *>(event)->globalPos());
89 }
90 return true;
91 default:;
92 }
93 }
94#endif
95 return QWidget::eventFilter(obj, event);
96}
97
98void PathSelection::showFileDialog()
99{
100 QString directory;
101 QFileInfo fileInfo(m_lineEdit->text());
102 if (fileInfo.exists()) {
103 if (fileInfo.isFile()) {
104 directory = fileInfo.absoluteDir().absolutePath();
105 } else {
106 directory = fileInfo.absolutePath();
107 }
108 }
109 if (m_customDialog) {
110 m_customDialog->setDirectory(directory);
111 if (m_customDialog->exec() == QFileDialog::Accepted) {
112 m_lineEdit->selectAll();
113 m_lineEdit->insert(m_customDialog->selectedFiles().join(SEARCH_PATH_SEP_CHAR));
114 }
115 } else {
116 QFileDialog dialog(this);
117 dialog.setDirectory(directory);
118 dialog.setFileMode(m_customMode);
119 if (window()) {
120 dialog.setWindowTitle(tr("Select path") % QStringLiteral(" - ") % window()->windowTitle());
121 } else {
122 dialog.setWindowTitle(tr("Select path"));
123 }
124 if (dialog.exec() == QFileDialog::Accepted) {
125 m_lineEdit->selectAll();
126 m_lineEdit->insert(dialog.selectedFiles().join(SEARCH_PATH_SEP_CHAR));
127 }
128 }
129}
130} // namespace QtUtilities
A QLineEdit with an embedded button for clearing its contents.
Definition: clearlineedit.h:14
PathSelection(QWidget *parent=nullptr)
Constructs a path selection widget.
bool eventFilter(QObject *obj, QEvent *event) override
QT_UTILITIES_EXPORT bool openLocalFileOrDir(const QString &path)
Shows the specified file or directory using the default file browser.