Qt Utilities 6.14.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
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 setTexts();
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::event(QEvent *event)
69{
70 switch (event->type()) {
71 case QEvent::LanguageChange:
72 setTexts();
73 break;
74 default:;
75 }
76 return QWidget::event(event);
77}
78
79bool PathSelection::eventFilter(QObject *obj, QEvent *event)
80{
81#ifndef QT_NO_CONTEXTMENU
82 if (obj == m_lineEdit) {
83 switch (event->type()) {
84 case QEvent::ContextMenu: {
85 unique_ptr<QMenu> menu(m_lineEdit->createStandardContextMenu());
86 menu->addSeparator();
87 connect(menu->addAction(QIcon::fromTheme(QStringLiteral("document-open")), tr("Select ...")), &QAction::triggered, this,
88 &PathSelection::showFileDialog);
89 QFileInfo fileInfo(m_lineEdit->text());
90 if (fileInfo.exists()) {
91 if (fileInfo.isFile()) {
92 connect(menu->addAction(QIcon::fromTheme(QStringLiteral("system-run")), tr("Open")), &QAction::triggered,
93 bind(&openLocalFileOrDir, m_lineEdit->text()));
94 } else if (fileInfo.isDir()) {
95 connect(menu->addAction(QIcon::fromTheme(QStringLiteral("system-file-manager")), tr("Explore")), &QAction::triggered,
96 bind(&openLocalFileOrDir, m_lineEdit->text()));
97 }
98 }
99 menu->exec(static_cast<QContextMenuEvent *>(event)->globalPos());
100 }
101 return true;
102 default:;
103 }
104 }
105#endif
106 return QWidget::eventFilter(obj, event);
107}
108
109void PathSelection::showFileDialog()
110{
111 QString directory;
112 QFileInfo fileInfo(m_lineEdit->text());
113 if (fileInfo.exists()) {
114 if (fileInfo.isFile()) {
115 directory = fileInfo.absoluteDir().absolutePath();
116 } else {
117 directory = fileInfo.absolutePath();
118 }
119 }
120 if (m_customDialog) {
121 m_customDialog->setDirectory(directory);
122 if (m_customDialog->exec() == QFileDialog::Accepted) {
123 m_lineEdit->selectAll();
124 m_lineEdit->insert(m_customDialog->selectedFiles().join(SEARCH_PATH_SEP_CHAR));
125 }
126 } else {
127 QFileDialog dialog(this);
128 dialog.setDirectory(directory);
129 dialog.setFileMode(m_customMode);
130 if (window()) {
131 dialog.setWindowTitle(tr("Select path") % QStringLiteral(" - ") % window()->windowTitle());
132 } else {
133 dialog.setWindowTitle(tr("Select path"));
134 }
135 if (dialog.exec() == QFileDialog::Accepted) {
136 m_lineEdit->selectAll();
137 m_lineEdit->insert(dialog.selectedFiles().join(SEARCH_PATH_SEP_CHAR));
138 }
139 }
140}
141
142void PathSelection::setTexts()
143{
144 m_button->setText(tr("Select ..."));
145}
146
147} // namespace QtUtilities
A QLineEdit with an embedded button for clearing its contents.
PathSelection(QWidget *parent=nullptr)
Constructs a path selection widget.
bool event(QEvent *event) override
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.