File: pathselection.cpp

package info (click to toggle)
martchus-qtutilities 6.15.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 780 kB
  • sloc: cpp: 5,908; xml: 37; sh: 25; ansic: 12; makefile: 12
file content (147 lines) | stat: -rw-r--r-- 4,500 bytes parent folder | download
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