Qt Utilities  6.4.1
Common Qt related C++ classes and routines used by my applications such as dialogs, widgets and models
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 
22 using namespace std;
23 
24 namespace QtUtilities {
25 
32 QCompleter *PathSelection::s_completer = nullptr;
33 
37 PathSelection::PathSelection(QWidget *parent)
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 
68 bool 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 
98 void 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
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.