~lubuntu-dev/lxde/lxqt-qtplugin

« back to all changes in this revision

Viewing changes to src/lxqtfiledialoghelper.cpp

  • Committer: GitHub
  • Author(s): PCMan
  • Date: 2017-08-26 14:00:17 UTC
  • mfrom: (63.1.10)
  • Revision ID: git-v1:bf96a1840410e9502bc5caabfc1a1bef0bdb9fae
Merge pull request #23 from lxde/pcman@file-dialog

LXQt file dialog

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
#include "lxqtfiledialoghelper.h"
 
2
 
 
3
#include <libfm-qt/libfmqt.h>
 
4
#include <libfm-qt/filedialog.h>
 
5
 
 
6
#include <QWindow>
 
7
#include <QDebug>
 
8
#include <QTimer>
 
9
#include <QSettings>
 
10
 
 
11
#include <memory>
 
12
 
 
13
static std::unique_ptr<Fm::LibFmQt> libfmQtContext_;
 
14
 
 
15
LXQtFileDialogHelper::LXQtFileDialogHelper() {
 
16
    if(!libfmQtContext_) {
 
17
        // initialize libfm-qt only once
 
18
        libfmQtContext_ = std::unique_ptr<Fm::LibFmQt>{new Fm::LibFmQt()};
 
19
    }
 
20
 
 
21
    // can only be used after libfm-qt initialization
 
22
    dlg_ = std::unique_ptr<Fm::FileDialog>(new Fm::FileDialog());
 
23
    connect(dlg_.get(), &Fm::FileDialog::accepted, [this]() {
 
24
        saveSettings();
 
25
        accept();
 
26
    });
 
27
    connect(dlg_.get(), &Fm::FileDialog::rejected, [this]() {
 
28
        saveSettings();
 
29
        reject();
 
30
    });
 
31
 
 
32
    connect(dlg_.get(), &Fm::FileDialog::fileSelected, this, &LXQtFileDialogHelper::fileSelected);
 
33
    connect(dlg_.get(), &Fm::FileDialog::filesSelected, this, &LXQtFileDialogHelper::filesSelected);
 
34
    connect(dlg_.get(), &Fm::FileDialog::currentChanged, this, &LXQtFileDialogHelper::currentChanged);
 
35
    connect(dlg_.get(), &Fm::FileDialog::directoryEntered, this, &LXQtFileDialogHelper::directoryEntered);
 
36
    connect(dlg_.get(), &Fm::FileDialog::filterSelected, this, &LXQtFileDialogHelper::filterSelected);
 
37
}
 
38
 
 
39
LXQtFileDialogHelper::~LXQtFileDialogHelper() {
 
40
}
 
41
 
 
42
void LXQtFileDialogHelper::exec() {
 
43
    dlg_->exec();
 
44
}
 
45
 
 
46
bool LXQtFileDialogHelper::show(Qt::WindowFlags windowFlags, Qt::WindowModality windowModality, QWindow* parent) {
 
47
    dlg_->setAttribute(Qt::WA_NativeWindow, true); // without this, sometimes windowHandle() will return nullptr
 
48
 
 
49
    dlg_->setWindowFlags(windowFlags);
 
50
    dlg_->setWindowModality(windowModality);
 
51
 
 
52
    // Reference: KDE implementation
 
53
    // https://github.com/KDE/plasma-integration/blob/master/src/platformtheme/kdeplatformfiledialoghelper.cpp
 
54
    dlg_->windowHandle()->setTransientParent(parent);
 
55
 
 
56
    loadSettings();
 
57
    // central positioning with respect to the parent window
 
58
    if(parent && parent->isVisible()) {
 
59
        dlg_->move(parent->x() + (parent->width() - dlg_->width()) / 2,
 
60
                   parent->y() + (parent->height() - dlg_->height()) / 2);
 
61
    }
 
62
 
 
63
    applyOptions();
 
64
 
 
65
    // NOTE: the timer here is required as a workaround borrowed from KDE. Without this, the dialog UI will be blocked.
 
66
    // QFileDialog calls our platform plugin to show our own native file dialog instead of showing its widget.
 
67
    // However, it still creates a hidden dialog internally, and then make it modal.
 
68
    // So user input from all other windows that are not the children of the QFileDialog widget will be blocked.
 
69
    // This includes our own dialog. After the return of this show() method, QFileDialog creates its own window and
 
70
    // then make it modal, which blocks our UI. The timer schedule a delayed popup of our file dialog, so we can
 
71
    // show again after QFileDialog and override the modal state. Then our UI can be unblocked.
 
72
    QTimer::singleShot(0, dlg_.get(), &QDialog::show);
 
73
    dlg_->setFocus();
 
74
    return true;
 
75
}
 
76
 
 
77
void LXQtFileDialogHelper::hide() {
 
78
    dlg_->hide();
 
79
}
 
80
 
 
81
bool LXQtFileDialogHelper::defaultNameFilterDisables() const {
 
82
    return false;
 
83
}
 
84
 
 
85
void LXQtFileDialogHelper::setDirectory(const QUrl& directory) {
 
86
    dlg_->setDirectory(directory);
 
87
}
 
88
 
 
89
QUrl LXQtFileDialogHelper::directory() const {
 
90
    return dlg_->directory();
 
91
}
 
92
 
 
93
void LXQtFileDialogHelper::selectFile(const QUrl& filename) {
 
94
    dlg_->selectFile(filename);
 
95
}
 
96
 
 
97
QList<QUrl> LXQtFileDialogHelper::selectedFiles() const {
 
98
    return dlg_->selectedFiles();
 
99
}
 
100
 
 
101
void LXQtFileDialogHelper::setFilter() {
 
102
    // FIXME: what's this?
 
103
    // The gtk+ 3 file dialog helper in Qt5 update options in this method.
 
104
    applyOptions();
 
105
}
 
106
 
 
107
void LXQtFileDialogHelper::selectNameFilter(const QString& filter) {
 
108
    dlg_->selectNameFilter(filter);
 
109
}
 
110
 
 
111
#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
 
112
QString LXQtFileDialogHelper::selectedMimeTypeFilter() const {
 
113
    return dlg_->selectedMimeTypeFilter();
 
114
}
 
115
 
 
116
void LXQtFileDialogHelper::selectMimeTypeFilter(const QString& filter) {
 
117
    dlg_->selectMimeTypeFilter(filter);
 
118
}
 
119
#endif
 
120
 
 
121
QString LXQtFileDialogHelper::selectedNameFilter() const {
 
122
    return dlg_->selectedNameFilter();
 
123
}
 
124
 
 
125
bool LXQtFileDialogHelper::isSupportedUrl(const QUrl& url) const {
 
126
    return dlg_->isSupportedUrl(url);
 
127
}
 
128
 
 
129
void LXQtFileDialogHelper::applyOptions() {
 
130
    auto& opt = options();
 
131
 
 
132
    // set title
 
133
    if(opt->windowTitle().isEmpty()) {
 
134
        dlg_->setWindowTitle(opt->acceptMode() == QFileDialogOptions::AcceptOpen ? tr("Open File")
 
135
                                                                                 : tr("Save File"));
 
136
    }
 
137
    else {
 
138
        dlg_->setWindowTitle(opt->windowTitle());
 
139
    }
 
140
 
 
141
    dlg_->setFilter(opt->filter());
 
142
    dlg_->setViewMode(opt->viewMode() == QFileDialogOptions::Detail ? Fm::FolderView::DetailedListMode
 
143
                                                                    : Fm::FolderView::CompactMode);
 
144
    dlg_->setFileMode(QFileDialog::FileMode(opt->fileMode()));
 
145
    dlg_->setAcceptMode(QFileDialog::AcceptMode(opt->acceptMode())); // also sets a default label for accept button
 
146
    // bool useDefaultNameFilters() const;
 
147
    dlg_->setNameFilters(opt->nameFilters());
 
148
    if(!opt->mimeTypeFilters().empty()) {
 
149
        dlg_->setMimeTypeFilters(opt->mimeTypeFilters());
 
150
    }
 
151
 
 
152
    dlg_->setDefaultSuffix(opt->defaultSuffix());
 
153
    // QStringList history() const;
 
154
 
 
155
    // explicitly set labels
 
156
    for(int i = 0; i < QFileDialogOptions::DialogLabelCount; ++i) {
 
157
        auto label = static_cast<QFileDialogOptions::DialogLabel>(i);
 
158
        if(opt->isLabelExplicitlySet(label)) {
 
159
            dlg_->setLabelText(static_cast<QFileDialog::DialogLabel>(label), opt->labelText(label));
 
160
        }
 
161
    }
 
162
 
 
163
    auto url = opt->initialDirectory();
 
164
    if(url.isValid()) {
 
165
        dlg_->setDirectory(url);
 
166
    }
 
167
 
 
168
 
 
169
#if QT_VERSION >= QT_VERSION_CHECK(5, 9, 0)
 
170
    auto filter = opt->initiallySelectedMimeTypeFilter();
 
171
    if(!filter.isEmpty()) {
 
172
        selectMimeTypeFilter(filter);
 
173
    }
 
174
    else {
 
175
        filter = opt->initiallySelectedNameFilter();
 
176
        if(!filter.isEmpty()) {
 
177
            selectNameFilter(opt->initiallySelectedNameFilter());
 
178
        }
 
179
    }
 
180
#else
 
181
    filter = opt->initiallySelectedNameFilter();
 
182
    if(!filter.isEmpty()) {
 
183
        selectNameFilter(filter);
 
184
    }
 
185
#endif
 
186
 
 
187
    auto selectedFiles = opt->initiallySelectedFiles();
 
188
    for(const auto& selectedFile: selectedFiles) {
 
189
        selectFile(selectedFile);
 
190
    }
 
191
    // QStringList supportedSchemes() const;
 
192
}
 
193
 
 
194
void LXQtFileDialogHelper::loadSettings() {
 
195
    QSettings settings(QSettings::UserScope, "lxqt", "filedialog");
 
196
    settings.beginGroup ("Sizes");
 
197
    dlg_->resize(settings.value("WindowSize", QSize(700, 500)).toSize());
 
198
    dlg_->setSplitterPos(settings.value("SplitterPos", 200).toInt());
 
199
    settings.endGroup();
 
200
}
 
201
 
 
202
void LXQtFileDialogHelper::saveSettings() {
 
203
    QSettings settings(QSettings::UserScope, "lxqt", "filedialog");
 
204
    settings.beginGroup ("Sizes");
 
205
    QSize windowSize = dlg_->size();
 
206
    if(settings.value("WindowSize") != windowSize) { // no redundant write
 
207
        settings.setValue("WindowSize", windowSize);
 
208
    }
 
209
    int splitterPos = dlg_->splitterPos();
 
210
    if(settings.value("SplitterPos") != splitterPos) {
 
211
        settings.setValue("SplitterPos", splitterPos);
 
212
    }
 
213
    settings.endGroup();
 
214
}
 
215
 
 
216
/*
 
217
FileDialogPlugin::FileDialogPlugin() {
 
218
 
 
219
}
 
220
 
 
221
QPlatformFileDialogHelper *FileDialogPlugin::createHelper() {
 
222
    return new LXQtFileDialogHelper();
 
223
}
 
224
*/