From 0b21c04489e1af39b6da8a525921e26d0ab7c7e5 Mon Sep 17 00:00:00 2001 From: Ilya Fedin Date: Sat, 26 Jun 2021 22:36:45 +0400 Subject: [PATCH] Remove the copy of gtk file dialog --- Telegram/CMakeLists.txt | 4 - .../platform/linux/file_utilities_linux.cpp | 14 - .../platform/linux/linux_gtk_file_dialog.cpp | 708 ------------------ .../platform/linux/linux_gtk_file_dialog.h | 27 - .../platform/linux/linux_gtk_integration.cpp | 58 -- .../platform/linux/linux_gtk_integration.h | 11 - .../linux/linux_gtk_integration_dummy.cpp | 11 - .../platform/linux/linux_gtk_integration_p.h | 37 - 8 files changed, 870 deletions(-) delete mode 100644 Telegram/SourceFiles/platform/linux/linux_gtk_file_dialog.cpp delete mode 100644 Telegram/SourceFiles/platform/linux/linux_gtk_file_dialog.h diff --git a/Telegram/CMakeLists.txt b/Telegram/CMakeLists.txt index 0b1e6f907..db827d37a 100644 --- a/Telegram/CMakeLists.txt +++ b/Telegram/CMakeLists.txt @@ -861,8 +861,6 @@ PRIVATE platform/linux/linux_gdk_helper.h platform/linux/linux_gsd_media_keys.cpp platform/linux/linux_gsd_media_keys.h - platform/linux/linux_gtk_file_dialog.cpp - platform/linux/linux_gtk_file_dialog.h platform/linux/linux_gtk_integration_dummy.cpp platform/linux/linux_gtk_integration_p.h platform/linux/linux_gtk_integration.cpp @@ -1194,8 +1192,6 @@ if (DESKTOP_APP_DISABLE_GTK_INTEGRATION) remove_target_sources(Telegram ${src_loc} platform/linux/linux_gdk_helper.cpp platform/linux/linux_gdk_helper.h - platform/linux/linux_gtk_file_dialog.cpp - platform/linux/linux_gtk_file_dialog.h platform/linux/linux_gtk_integration_p.h platform/linux/linux_gtk_integration.cpp platform/linux/linux_gtk_open_with_dialog.cpp diff --git a/Telegram/SourceFiles/platform/linux/file_utilities_linux.cpp b/Telegram/SourceFiles/platform/linux/file_utilities_linux.cpp index b3e65ff0c..a692a702a 100644 --- a/Telegram/SourceFiles/platform/linux/file_utilities_linux.cpp +++ b/Telegram/SourceFiles/platform/linux/file_utilities_linux.cpp @@ -117,20 +117,6 @@ bool Get( } } #endif // !DESKTOP_APP_DISABLE_DBUS_INTEGRATION - if (const auto integration = GtkIntegration::Instance()) { - const auto result = integration->getFileDialog( - parent, - files, - remoteContent, - caption, - filter, - type, - startFile); - - if (result.has_value()) { - return *result; - } - } return ::FileDialog::internal::GetDefault( parent, files, diff --git a/Telegram/SourceFiles/platform/linux/linux_gtk_file_dialog.cpp b/Telegram/SourceFiles/platform/linux/linux_gtk_file_dialog.cpp deleted file mode 100644 index eac330ffa..000000000 --- a/Telegram/SourceFiles/platform/linux/linux_gtk_file_dialog.cpp +++ /dev/null @@ -1,708 +0,0 @@ -/* -This file is part of Telegram Desktop, -the official desktop application for the Telegram messaging service. - -For license and copyright information please follow this link: -https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL -*/ -#include "platform/linux/linux_gtk_file_dialog.h" - -#include "platform/platform_file_utilities.h" -#include "platform/linux/linux_gtk_integration_p.h" -#include "platform/linux/linux_gdk_helper.h" -#include "platform/linux/linux_desktop_environment.h" -#include "lang/lang_keys.h" -#include "storage/localstorage.h" -#include "base/qt_adapters.h" - -#include -#include -#include - -namespace Platform { -namespace FileDialog { -namespace Gtk { -namespace { - -using namespace Platform::Gtk; -using Type = ::FileDialog::internal::Type; - -// GTK file chooser image preview: thanks to Chromium - -// The size of the preview we display for selected image files. We set height -// larger than width because generally there is more free space vertically -// than horiztonally (setting the preview image will alway expand the width of -// the dialog, but usually not the height). The image's aspect ratio will always -// be preserved. -constexpr auto kPreviewWidth = 256; -constexpr auto kPreviewHeight = 512; - -const char *filterRegExp = -"^(.*)\\(([a-zA-Z0-9_.,*? +;#\\-\\[\\]@\\{\\}/!<>\\$%&=^~:\\|]*)\\)$"; - -QStringList makeFilterList(const QString &filter) { - QString f(filter); - - if (f.isEmpty()) - return QStringList(); - - QString sep(QLatin1String(";;")); - int i = f.indexOf(sep, 0); - if (i == -1) { - if (f.indexOf(QLatin1Char('\n'), 0) != -1) { - sep = QLatin1Char('\n'); - i = f.indexOf(sep, 0); - } - } - - return f.split(sep); -} - -// Makes a list of filters from a normal filter string "Image Files (*.png *.jpg)" -QStringList cleanFilterList(const QString &filter) { - QRegExp regexp(QString::fromLatin1(filterRegExp)); - Assert(regexp.isValid()); - QString f = filter; - int i = regexp.indexIn(f); - if (i >= 0) - f = regexp.cap(2); - return f.split(QLatin1Char(' '), base::QStringSkipEmptyParts); -} - -bool Supported() { - return (gtk_widget_hide_on_delete != nullptr) - && (gtk_clipboard_store != nullptr) - && (gtk_clipboard_get != nullptr) - && (gtk_widget_destroy != nullptr) - && (gtk_dialog_get_type != nullptr) - && (gtk_dialog_run != nullptr) - && (gtk_widget_realize != nullptr) - && (gdk_window_set_modal_hint != nullptr) - && (gtk_widget_show != nullptr) - && (gdk_window_focus != nullptr) - && (gtk_widget_hide != nullptr) - && (gtk_widget_hide_on_delete != nullptr) - && (gtk_file_chooser_dialog_new != nullptr) - && (gtk_file_chooser_get_type != nullptr) - && (gtk_file_chooser_set_current_folder != nullptr) - && (gtk_file_chooser_get_current_folder != nullptr) - && (gtk_file_chooser_set_current_name != nullptr) - && (gtk_file_chooser_select_filename != nullptr) - && (gtk_file_chooser_get_filenames != nullptr) - && (gtk_file_chooser_set_filter != nullptr) - && (gtk_file_chooser_get_filter != nullptr) - && (gtk_window_get_type != nullptr) - && (gtk_window_set_title != nullptr) - && (gtk_file_chooser_set_local_only != nullptr) - && (gtk_file_chooser_set_action != nullptr) - && (gtk_file_chooser_set_select_multiple != nullptr) - && (gtk_file_chooser_set_do_overwrite_confirmation != nullptr) - && (gtk_file_chooser_remove_filter != nullptr) - && (gtk_file_filter_set_name != nullptr) - && (gtk_file_filter_add_pattern != nullptr) - && (gtk_file_chooser_add_filter != nullptr) - && (gtk_file_filter_new != nullptr); -} - -bool PreviewSupported() { - return (gdk_pixbuf_new_from_file_at_size != nullptr); -} - -bool CustomButtonsSupported() { - return (gtk_dialog_get_widget_for_response != nullptr) - && (gtk_button_set_label != nullptr) - && (gtk_button_get_type != nullptr); -} - -// This is a patched copy of qgtk2 theme plugin. -// We need to use our own gtk file dialog instead of -// styling Qt file dialog, because Qt only works with gtk2. -// We need to be able to work with gtk2 and gtk3, because -// we use gtk3 to work with appindicator3. -class QGtkDialog : public QWindow { -public: - QGtkDialog(GtkWidget *gtkWidget); - ~QGtkDialog(); - - GtkDialog *gtkDialog() const; - - void exec(); - void show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent); - void hide(); - - rpl::producer<> accept(); - rpl::producer<> reject(); - -protected: - static void onResponse(QGtkDialog *dialog, int response); - -private: - void onParentWindowDestroyed(); - - GtkWidget *gtkWidget = nullptr; - - rpl::event_stream<> _accept; - rpl::event_stream<> _reject; - - bool _destroyedConnected = false; - -}; - -class GtkFileDialog : public QDialog { -public: - GtkFileDialog( - QWidget *parent = nullptr, - const QString &caption = QString(), - const QString &directory = QString(), - const QString &filter = QString()); - ~GtkFileDialog(); - - void setVisible(bool visible) override; - - void setWindowTitle(const QString &windowTitle) { - _windowTitle = windowTitle; - } - void setAcceptMode(QFileDialog::AcceptMode acceptMode) { - _acceptMode = acceptMode; - } - void setFileMode(QFileDialog::FileMode fileMode) { - _fileMode = fileMode; - } - void setOption(QFileDialog::Option option, bool on = true) { - if (on) { - _options |= option; - } else { - _options &= ~option; - } - } - - int exec() override; - - bool defaultNameFilterDisables() const; - void setDirectory(const QString &directory); - QDir directory() const; - void selectFile(const QString &filename); - QStringList selectedFiles() const; - void setFilter(); - void selectNameFilter(const QString &filter); - QString selectedNameFilter() const; - -private: - static void onSelectionChanged(GtkDialog *dialog, GtkFileDialog *helper); - static void onCurrentFolderChanged(GtkFileDialog *helper); - static void onUpdatePreview(GtkDialog *gtkDialog, GtkFileDialog *helper); - void applyOptions(); - void setNameFilters(const QStringList &filters); - - void showHelper(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent); - void hideHelper(); - - void onAccepted(); - void onRejected(); - - // Options - QFileDialog::Options _options; - QString _windowTitle = "Choose file"; - QString _initialDirectory; - QStringList _initialFiles; - QStringList _nameFilters; - QFileDialog::AcceptMode _acceptMode = QFileDialog::AcceptOpen; - QFileDialog::FileMode _fileMode = QFileDialog::ExistingFile; - - QString _dir; - QStringList _selection; - QHash _filters; - QHash _filterNames; - QScopedPointer d; - GtkWidget *_preview = nullptr; - - rpl::lifetime _lifetime; -}; - -QGtkDialog::QGtkDialog(GtkWidget *gtkWidget) : gtkWidget(gtkWidget) { - g_signal_connect_swapped(G_OBJECT(gtkWidget), "response", G_CALLBACK(onResponse), this); - g_signal_connect(G_OBJECT(gtkWidget), "delete-event", G_CALLBACK(gtk_widget_hide_on_delete), nullptr); -} - -QGtkDialog::~QGtkDialog() { - gtk_clipboard_store(gtk_clipboard_get(GDK_SELECTION_CLIPBOARD)); - gtk_widget_destroy(gtkWidget); -} - -GtkDialog *QGtkDialog::gtkDialog() const { - return GTK_DIALOG(gtkWidget); -} - -void QGtkDialog::exec() { - if (modality() == Qt::ApplicationModal) { - // block input to the whole app, including other GTK dialogs - gtk_dialog_run(gtkDialog()); - } else { - // block input to the window, allow input to other GTK dialogs - QEventLoop loop; - rpl::lifetime lifetime; - - accept( - ) | rpl::start_with_next([&] { - loop.quit(); - }, lifetime); - - reject( - ) | rpl::start_with_next([&] { - loop.quit(); - }, lifetime); - - loop.exec(); - } -} - -void QGtkDialog::show(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) { - if (!std::exchange(_destroyedConnected, true)) { - connect(parent, &QWindow::destroyed, this, [=] { onParentWindowDestroyed(); }); - } - setParent(parent); - setFlags(flags); - setModality(modality); - - gtk_widget_realize(gtkWidget); // creates X window - - if (parent) { - internal::GdkSetTransientFor(gtk_widget_get_window(gtkWidget), parent); - } - - if (modality != Qt::NonModal) { - gdk_window_set_modal_hint(gtk_widget_get_window(gtkWidget), true); - QGuiApplicationPrivate::showModalWindow(this); - } - - gtk_widget_show(gtkWidget); - gdk_window_focus(gtk_widget_get_window(gtkWidget), 0); -} - -void QGtkDialog::hide() { - QGuiApplicationPrivate::hideModalWindow(this); - gtk_widget_hide(gtkWidget); -} - -rpl::producer<> QGtkDialog::accept() { - return _accept.events(); -} - -rpl::producer<> QGtkDialog::reject() { - return _reject.events(); -} - -void QGtkDialog::onResponse(QGtkDialog *dialog, int response) { - if (response == GTK_RESPONSE_OK) - dialog->_accept.fire({}); - else - dialog->_reject.fire({}); -} - -void QGtkDialog::onParentWindowDestroyed() { - // The Gtk*DialogHelper classes own this object. Make sure the parent doesn't delete it. - setParent(nullptr); -} - -GtkFileDialog::GtkFileDialog(QWidget *parent, const QString &caption, const QString &directory, const QString &filter) : QDialog(parent) -, _windowTitle(caption) -, _initialDirectory(directory) { - auto filters = makeFilterList(filter); - const int numFilters = filters.count(); - _nameFilters.reserve(numFilters); - for (int i = 0; i < numFilters; ++i) { - _nameFilters << filters[i].simplified(); - } - - d.reset(new QGtkDialog(gtk_file_chooser_dialog_new("", nullptr, - GTK_FILE_CHOOSER_ACTION_OPEN, - tr::lng_cancel(tr::now).toUtf8().constData(), GTK_RESPONSE_CANCEL, - tr::lng_box_ok(tr::now).toUtf8().constData(), GTK_RESPONSE_OK, nullptr))); - - d.data()->accept( - ) | rpl::start_with_next([=] { - onAccepted(); - }, _lifetime); - - d.data()->reject( - ) | rpl::start_with_next([=] { - onRejected(); - }, _lifetime); - - g_signal_connect(GTK_FILE_CHOOSER(d->gtkDialog()), "selection-changed", G_CALLBACK(onSelectionChanged), this); - g_signal_connect_swapped(GTK_FILE_CHOOSER(d->gtkDialog()), "current-folder-changed", G_CALLBACK(onCurrentFolderChanged), this); - - if (PreviewSupported()) { - _preview = gtk_image_new(); - g_signal_connect(G_OBJECT(d->gtkDialog()), "update-preview", G_CALLBACK(onUpdatePreview), this); - gtk_file_chooser_set_preview_widget(GTK_FILE_CHOOSER(d->gtkDialog()), _preview); - } -} - -GtkFileDialog::~GtkFileDialog() { -} - -void GtkFileDialog::showHelper(Qt::WindowFlags flags, Qt::WindowModality modality, QWindow *parent) { - _dir.clear(); - _selection.clear(); - - applyOptions(); - return d->show(flags, modality, parent); -} - -void GtkFileDialog::setVisible(bool visible) { - if (visible) { - if (testAttribute(Qt::WA_WState_ExplicitShowHide) && !testAttribute(Qt::WA_WState_Hidden)) { - return; - } - } else if (testAttribute(Qt::WA_WState_ExplicitShowHide) && testAttribute(Qt::WA_WState_Hidden)) { - return; - } - - if (visible) { - showHelper(windowFlags(), windowModality(), parentWidget() ? parentWidget()->windowHandle() : nullptr); - } else { - hideHelper(); - } - - // Set WA_DontShowOnScreen so that QDialog::setVisible(visible) below - // updates the state correctly, but skips showing the non-native version: - setAttribute(Qt::WA_DontShowOnScreen); - - QDialog::setVisible(visible); -} - -int GtkFileDialog::exec() { - d->setModality(windowModality()); - - bool deleteOnClose = testAttribute(Qt::WA_DeleteOnClose); - setAttribute(Qt::WA_DeleteOnClose, false); - - bool wasShowModal = testAttribute(Qt::WA_ShowModal); - setAttribute(Qt::WA_ShowModal, true); - setResult(0); - - show(); - - QPointer guard = this; - d->exec(); - if (guard.isNull()) - return QDialog::Rejected; - - setAttribute(Qt::WA_ShowModal, wasShowModal); - - return result(); -} - -void GtkFileDialog::hideHelper() { - // After GtkFileChooserDialog has been hidden, gtk_file_chooser_get_current_folder() - // & gtk_file_chooser_get_filenames() will return bogus values -> cache the actual - // values before hiding the dialog - _dir = directory().absolutePath(); - _selection = selectedFiles(); - - d->hide(); -} - -bool GtkFileDialog::defaultNameFilterDisables() const { - return false; -} - -void GtkFileDialog::setDirectory(const QString &directory) { - GtkDialog *gtkDialog = d->gtkDialog(); - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(gtkDialog), directory.toUtf8().constData()); -} - -QDir GtkFileDialog::directory() const { - // While GtkFileChooserDialog is hidden, gtk_file_chooser_get_current_folder() - // returns a bogus value -> return the cached value before hiding - if (!_dir.isEmpty()) - return _dir; - - QString ret; - GtkDialog *gtkDialog = d->gtkDialog(); - gchar *folder = gtk_file_chooser_get_current_folder(GTK_FILE_CHOOSER(gtkDialog)); - if (folder) { - ret = QString::fromUtf8(folder); - g_free(folder); - } - return QDir(ret); -} - -void GtkFileDialog::selectFile(const QString &filename) { - _initialFiles.clear(); - _initialFiles.append(filename); -} - -QStringList GtkFileDialog::selectedFiles() const { - // While GtkFileChooserDialog is hidden, gtk_file_chooser_get_filenames() - // returns a bogus value -> return the cached value before hiding - if (!_selection.isEmpty()) - return _selection; - - QStringList selection; - GtkDialog *gtkDialog = d->gtkDialog(); - GSList *filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(gtkDialog)); - for (GSList *it = filenames; it; it = it->next) - selection += QString::fromUtf8((const char*)it->data); - g_slist_free(filenames); - return selection; -} - -void GtkFileDialog::setFilter() { - applyOptions(); -} - -void GtkFileDialog::selectNameFilter(const QString &filter) { - GtkFileFilter *gtkFilter = _filters.value(filter); - if (gtkFilter) { - GtkDialog *gtkDialog = d->gtkDialog(); - gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(gtkDialog), gtkFilter); - } -} - -QString GtkFileDialog::selectedNameFilter() const { - GtkDialog *gtkDialog = d->gtkDialog(); - GtkFileFilter *gtkFilter = gtk_file_chooser_get_filter(GTK_FILE_CHOOSER(gtkDialog)); - return _filterNames.value(gtkFilter); -} - -void GtkFileDialog::onAccepted() { - accept(); - -// QString filter = selectedNameFilter(); -// if (filter.isEmpty()) -// emit filterSelected(filter); - -// QList files = selectedFiles(); -// emit filesSelected(files); -// if (files.count() == 1) -// emit fileSelected(files.first()); -} - -void GtkFileDialog::onRejected() { - reject(); - -// -} - -void GtkFileDialog::onSelectionChanged(GtkDialog *gtkDialog, GtkFileDialog *helper) { -// QString selection; -// gchar *filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(gtkDialog)); -// if (filename) { -// selection = QString::fromUtf8(filename); -// g_free(filename); -// } -// emit helper->currentChanged(QUrl::fromLocalFile(selection)); -} - -void GtkFileDialog::onCurrentFolderChanged(GtkFileDialog *dialog) { -// emit dialog->directoryEntered(dialog->directory()); -} - -void GtkFileDialog::onUpdatePreview(GtkDialog *gtkDialog, GtkFileDialog *helper) { - auto filename = gtk_file_chooser_get_preview_filename(GTK_FILE_CHOOSER(gtkDialog)); - if (!filename) { - gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(gtkDialog), false); - return; - } - - // Don't attempt to open anything which isn't a regular file. If a named pipe, - // this may hang. See https://crbug.com/534754. - struct stat stat_buf; - if (stat(filename, &stat_buf) != 0 || !S_ISREG(stat_buf.st_mode)) { - g_free(filename); - gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(gtkDialog), false); - return; - } - - // This will preserve the image's aspect ratio. - auto pixbuf = gdk_pixbuf_new_from_file_at_size(filename, kPreviewWidth, kPreviewHeight, nullptr); - g_free(filename); - if (pixbuf) { - gtk_image_set_from_pixbuf(GTK_IMAGE(helper->_preview), pixbuf); - g_object_unref(pixbuf); - } - gtk_file_chooser_set_preview_widget_active(GTK_FILE_CHOOSER(gtkDialog), pixbuf ? true : false); -} - -GtkFileChooserAction gtkFileChooserAction(QFileDialog::FileMode fileMode, QFileDialog::AcceptMode acceptMode) { - switch (fileMode) { - case QFileDialog::AnyFile: - case QFileDialog::ExistingFile: - case QFileDialog::ExistingFiles: - if (acceptMode == QFileDialog::AcceptOpen) - return GTK_FILE_CHOOSER_ACTION_OPEN; - else - return GTK_FILE_CHOOSER_ACTION_SAVE; - case QFileDialog::Directory: - default: - if (acceptMode == QFileDialog::AcceptOpen) - return GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER; - else - return GTK_FILE_CHOOSER_ACTION_CREATE_FOLDER; - } -} - -void GtkFileDialog::applyOptions() { - GtkDialog *gtkDialog = d->gtkDialog(); - - gtk_window_set_title(GTK_WINDOW(gtkDialog), _windowTitle.toUtf8().constData()); - gtk_file_chooser_set_local_only(GTK_FILE_CHOOSER(gtkDialog), true); - - const GtkFileChooserAction action = gtkFileChooserAction(_fileMode, _acceptMode); - gtk_file_chooser_set_action(GTK_FILE_CHOOSER(gtkDialog), action); - - const bool selectMultiple = (_fileMode == QFileDialog::ExistingFiles); - gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(gtkDialog), selectMultiple); - - const bool confirmOverwrite = !_options.testFlag(QFileDialog::DontConfirmOverwrite); - gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(gtkDialog), confirmOverwrite); - - if (!_nameFilters.isEmpty()) - setNameFilters(_nameFilters); - - if (!_initialDirectory.isEmpty()) - setDirectory(_initialDirectory); - - for_const (const auto &filename, _initialFiles) { - if (_acceptMode == QFileDialog::AcceptSave) { - QFileInfo fi(filename); - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(gtkDialog), fi.path().toUtf8().constData()); - gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(gtkDialog), fi.fileName().toUtf8().constData()); - } else if (filename.endsWith('/')) { - gtk_file_chooser_set_current_folder(GTK_FILE_CHOOSER(gtkDialog), filename.toUtf8().constData()); - } else { - gtk_file_chooser_select_filename(GTK_FILE_CHOOSER(gtkDialog), filename.toUtf8().constData()); - } - } - - const QString initialNameFilter = _nameFilters.isEmpty() ? QString() : _nameFilters.front(); - if (!initialNameFilter.isEmpty()) - selectNameFilter(initialNameFilter); - - if (CustomButtonsSupported()) { - GtkWidget *acceptButton = gtk_dialog_get_widget_for_response(gtkDialog, GTK_RESPONSE_OK); - if (acceptButton) { - /*if (opts->isLabelExplicitlySet(QFileDialogOptions::Accept)) - gtk_button_set_label(GTK_BUTTON(acceptButton), opts->labelText(QFileDialogOptions::Accept).toUtf8().constData()); - else*/ if (_acceptMode == QFileDialog::AcceptOpen) - gtk_button_set_label(GTK_BUTTON(acceptButton), tr::lng_open_link(tr::now).toUtf8().constData()); - else - gtk_button_set_label(GTK_BUTTON(acceptButton), tr::lng_settings_save(tr::now).toUtf8().constData()); - } - - GtkWidget *rejectButton = gtk_dialog_get_widget_for_response(gtkDialog, GTK_RESPONSE_CANCEL); - if (rejectButton) { - /*if (opts->isLabelExplicitlySet(QFileDialogOptions::Reject)) - gtk_button_set_label(GTK_BUTTON(rejectButton), opts->labelText(QFileDialogOptions::Reject).toUtf8().constData()); - else*/ - gtk_button_set_label(GTK_BUTTON(rejectButton), tr::lng_cancel(tr::now).toUtf8().constData()); - } - } -} - -void GtkFileDialog::setNameFilters(const QStringList &filters) { - GtkDialog *gtkDialog = d->gtkDialog(); - Q_FOREACH (GtkFileFilter *filter, _filters) - gtk_file_chooser_remove_filter(GTK_FILE_CHOOSER(gtkDialog), filter); - - _filters.clear(); - _filterNames.clear(); - - for_const (auto &filter, filters) { - GtkFileFilter *gtkFilter = gtk_file_filter_new(); - auto name = filter;//.left(filter.indexOf(QLatin1Char('('))); - auto extensions = cleanFilterList(filter); - - gtk_file_filter_set_name(gtkFilter, name.isEmpty() ? extensions.join(QStringLiteral(", ")).toUtf8().constData() : name.toUtf8().constData()); - for_const (auto &ext, extensions) { - auto caseInsensitiveExt = QString(); - caseInsensitiveExt.reserve(4 * ext.size()); - for_const (auto ch, ext) { - auto chLower = ch.toLower(); - auto chUpper = ch.toUpper(); - if (chLower != chUpper) { - caseInsensitiveExt.append('[').append(chLower).append(chUpper).append(']'); - } else { - caseInsensitiveExt.append(ch); - } - } - - gtk_file_filter_add_pattern(gtkFilter, caseInsensitiveExt.toUtf8().constData()); - } - - gtk_file_chooser_add_filter(GTK_FILE_CHOOSER(gtkDialog), gtkFilter); - - _filters.insert(filter, gtkFilter); - _filterNames.insert(gtkFilter, filter); - } -} - -} // namespace - -std::optional Get( - QPointer parent, - QStringList &files, - QByteArray &remoteContent, - const QString &caption, - const QString &filter, - Type type, - QString startFile) { - if (!Supported() - || (!qEnvironmentVariableIsSet("TDESKTOP_USE_GTK_FILE_DIALOG") - && !DesktopEnvironment::IsGtkBased())) { - return std::nullopt; - } - - if (cDialogLastPath().isEmpty()) { - InitLastPath(); - } - - GtkFileDialog dialog(parent, caption, QString(), filter); - - dialog.setModal(true); - if (type == Type::ReadFile || type == Type::ReadFiles) { - dialog.setFileMode((type == Type::ReadFiles) ? QFileDialog::ExistingFiles : QFileDialog::ExistingFile); - dialog.setAcceptMode(QFileDialog::AcceptOpen); - } else if (type == Type::ReadFolder) { - dialog.setAcceptMode(QFileDialog::AcceptOpen); - dialog.setFileMode(QFileDialog::Directory); - dialog.setOption(QFileDialog::ShowDirsOnly); - } else { - dialog.setFileMode(QFileDialog::AnyFile); - dialog.setAcceptMode(QFileDialog::AcceptSave); - } - if (startFile.isEmpty() || startFile.at(0) != '/') { - startFile = cDialogLastPath() + '/' + startFile; - } - dialog.selectFile(startFile); - - const auto res = dialog.exec(); - - if (type != Type::ReadFolder) { - // Save last used directory for all queries except directory choosing. - const auto path = dialog.directory().absolutePath(); - if (!path.isEmpty() && path != cDialogLastPath()) { - cSetDialogLastPath(path); - Local::writeSettings(); - } - } - - if (res == QDialog::Accepted) { - if (type == Type::ReadFiles) { - files = dialog.selectedFiles(); - } else { - files = dialog.selectedFiles().mid(0, 1); - } - return true; - } - - files = QStringList(); - remoteContent = QByteArray(); - return false; -} - -} // namespace Gtk -} // namespace FileDialog -} // namespace Platform diff --git a/Telegram/SourceFiles/platform/linux/linux_gtk_file_dialog.h b/Telegram/SourceFiles/platform/linux/linux_gtk_file_dialog.h deleted file mode 100644 index b12c7f415..000000000 --- a/Telegram/SourceFiles/platform/linux/linux_gtk_file_dialog.h +++ /dev/null @@ -1,27 +0,0 @@ -/* -This file is part of Telegram Desktop, -the official desktop application for the Telegram messaging service. - -For license and copyright information please follow this link: -https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL -*/ -#pragma once - -#include "core/file_utilities.h" - -namespace Platform { -namespace FileDialog { -namespace Gtk { - -std::optional Get( - QPointer parent, - QStringList &files, - QByteArray &remoteContent, - const QString &caption, - const QString &filter, - ::FileDialog::internal::Type type, - QString startFile); - -} // namespace Gtk -} // namespace FileDialog -} // namespace Platform diff --git a/Telegram/SourceFiles/platform/linux/linux_gtk_integration.cpp b/Telegram/SourceFiles/platform/linux/linux_gtk_integration.cpp index 8fb76c3ac..258a779e5 100644 --- a/Telegram/SourceFiles/platform/linux/linux_gtk_integration.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_gtk_integration.cpp @@ -11,7 +11,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL #include "base/platform/linux/base_linux_gtk_integration_p.h" #include "platform/linux/linux_gtk_integration_p.h" #include "platform/linux/linux_gdk_helper.h" -#include "platform/linux/linux_gtk_file_dialog.h" #include "platform/linux/linux_gtk_open_with_dialog.h" namespace Platform { @@ -61,48 +60,14 @@ void GtkIntegration::load() { auto &lib = BaseGtkIntegration::Instance()->library(); LOAD_GTK_SYMBOL(lib, gtk_widget_show); - LOAD_GTK_SYMBOL(lib, gtk_widget_hide); LOAD_GTK_SYMBOL(lib, gtk_widget_get_window); LOAD_GTK_SYMBOL(lib, gtk_widget_realize); - LOAD_GTK_SYMBOL(lib, gtk_widget_hide_on_delete); LOAD_GTK_SYMBOL(lib, gtk_widget_destroy); LOAD_GTK_SYMBOL(lib, gtk_clipboard_get); - LOAD_GTK_SYMBOL(lib, gtk_clipboard_store); LOAD_GTK_SYMBOL(lib, gtk_clipboard_wait_for_contents); LOAD_GTK_SYMBOL(lib, gtk_clipboard_wait_for_image); LOAD_GTK_SYMBOL(lib, gtk_selection_data_targets_include_image); LOAD_GTK_SYMBOL(lib, gtk_selection_data_free); - LOAD_GTK_SYMBOL(lib, gtk_file_chooser_dialog_new); - LOAD_GTK_SYMBOL(lib, gtk_file_chooser_get_type); - LOAD_GTK_SYMBOL(lib, gtk_image_get_type); - LOAD_GTK_SYMBOL(lib, gtk_file_chooser_set_current_folder); - LOAD_GTK_SYMBOL(lib, gtk_file_chooser_get_current_folder); - LOAD_GTK_SYMBOL(lib, gtk_file_chooser_set_current_name); - LOAD_GTK_SYMBOL(lib, gtk_file_chooser_select_filename); - LOAD_GTK_SYMBOL(lib, gtk_file_chooser_get_filenames); - LOAD_GTK_SYMBOL(lib, gtk_file_chooser_set_filter); - LOAD_GTK_SYMBOL(lib, gtk_file_chooser_get_filter); - LOAD_GTK_SYMBOL(lib, gtk_window_get_type); - LOAD_GTK_SYMBOL(lib, gtk_window_set_title); - LOAD_GTK_SYMBOL(lib, gtk_file_chooser_set_local_only); - LOAD_GTK_SYMBOL(lib, gtk_file_chooser_set_action); - LOAD_GTK_SYMBOL(lib, gtk_file_chooser_set_select_multiple); - LOAD_GTK_SYMBOL(lib, gtk_file_chooser_set_do_overwrite_confirmation); - LOAD_GTK_SYMBOL(lib, gtk_file_chooser_remove_filter); - LOAD_GTK_SYMBOL(lib, gtk_file_filter_set_name); - LOAD_GTK_SYMBOL(lib, gtk_file_filter_add_pattern); - LOAD_GTK_SYMBOL(lib, gtk_file_chooser_add_filter); - LOAD_GTK_SYMBOL(lib, gtk_file_chooser_set_preview_widget); - LOAD_GTK_SYMBOL(lib, gtk_file_chooser_get_preview_filename); - LOAD_GTK_SYMBOL(lib, gtk_file_chooser_set_preview_widget_active); - LOAD_GTK_SYMBOL(lib, gtk_file_filter_new); - LOAD_GTK_SYMBOL(lib, gtk_image_new); - LOAD_GTK_SYMBOL(lib, gtk_image_set_from_pixbuf); - - LOAD_GTK_SYMBOL(lib, gdk_window_set_modal_hint); - LOAD_GTK_SYMBOL(lib, gdk_window_focus); - LOAD_GTK_SYMBOL(lib, gtk_dialog_get_type); - LOAD_GTK_SYMBOL(lib, gtk_dialog_run); LOAD_GTK_SYMBOL(lib, gdk_atom_intern); @@ -111,7 +76,6 @@ void GtkIntegration::load() { LOAD_GTK_SYMBOL(lib, gdk_display_get_primary_monitor); LOAD_GTK_SYMBOL(lib, gdk_monitor_get_scale_factor); - LOAD_GTK_SYMBOL(lib, gdk_pixbuf_new_from_file_at_size); LOAD_GTK_SYMBOL(lib, gdk_pixbuf_get_has_alpha); LOAD_GTK_SYMBOL(lib, gdk_pixbuf_get_pixels); LOAD_GTK_SYMBOL(lib, gdk_pixbuf_get_width); @@ -120,10 +84,6 @@ void GtkIntegration::load() { GdkHelperLoad(lib); - LOAD_GTK_SYMBOL(lib, gtk_dialog_get_widget_for_response); - LOAD_GTK_SYMBOL(lib, gtk_button_set_label); - LOAD_GTK_SYMBOL(lib, gtk_button_get_type); - LOAD_GTK_SYMBOL(lib, gtk_app_chooser_dialog_new); LOAD_GTK_SYMBOL(lib, gtk_app_chooser_get_app_info); LOAD_GTK_SYMBOL(lib, gtk_app_chooser_get_type); @@ -158,24 +118,6 @@ std::optional GtkIntegration::scaleFactor() const { return gdk_monitor_get_scale_factor(monitor); } -std::optional GtkIntegration::getFileDialog( - QPointer parent, - QStringList &files, - QByteArray &remoteContent, - const QString &caption, - const QString &filter, - ::FileDialog::internal::Type type, - QString startFile) const { - return FileDialog::Gtk::Get( - parent, - files, - remoteContent, - caption, - filter, - type, - startFile); -} - bool GtkIntegration::showOpenWithDialog(const QString &filepath) const { return File::internal::ShowGtkOpenWithDialog(filepath); } diff --git a/Telegram/SourceFiles/platform/linux/linux_gtk_integration.h b/Telegram/SourceFiles/platform/linux/linux_gtk_integration.h index e1ff44e63..d10b7da56 100644 --- a/Telegram/SourceFiles/platform/linux/linux_gtk_integration.h +++ b/Telegram/SourceFiles/platform/linux/linux_gtk_integration.h @@ -7,8 +7,6 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL */ #pragma once -#include "core/file_utilities.h" - namespace Platform { namespace internal { @@ -20,15 +18,6 @@ public: [[nodiscard]] std::optional scaleFactor() const; - [[nodiscard]] std::optional getFileDialog( - QPointer parent, - QStringList &files, - QByteArray &remoteContent, - const QString &caption, - const QString &filter, - ::FileDialog::internal::Type type, - QString startFile) const; - [[nodiscard]] bool showOpenWithDialog(const QString &filepath) const; [[nodiscard]] QImage getImageFromClipboard() const; diff --git a/Telegram/SourceFiles/platform/linux/linux_gtk_integration_dummy.cpp b/Telegram/SourceFiles/platform/linux/linux_gtk_integration_dummy.cpp index a0dfb2ba0..dddabca80 100644 --- a/Telegram/SourceFiles/platform/linux/linux_gtk_integration_dummy.cpp +++ b/Telegram/SourceFiles/platform/linux/linux_gtk_integration_dummy.cpp @@ -24,17 +24,6 @@ std::optional GtkIntegration::scaleFactor() const { return std::nullopt; } -std::optional GtkIntegration::getFileDialog( - QPointer parent, - QStringList &files, - QByteArray &remoteContent, - const QString &caption, - const QString &filter, - ::FileDialog::internal::Type type, - QString startFile) const { - return std::nullopt; -} - bool GtkIntegration::showOpenWithDialog(const QString &filepath) const { return false; } diff --git a/Telegram/SourceFiles/platform/linux/linux_gtk_integration_p.h b/Telegram/SourceFiles/platform/linux/linux_gtk_integration_p.h index d518e816b..fa28e8c5f 100644 --- a/Telegram/SourceFiles/platform/linux/linux_gtk_integration_p.h +++ b/Telegram/SourceFiles/platform/linux/linux_gtk_integration_p.h @@ -16,59 +16,22 @@ namespace Platform { namespace Gtk { inline void (*gtk_widget_show)(GtkWidget *widget) = nullptr; -inline void (*gtk_widget_hide)(GtkWidget *widget) = nullptr; inline GdkWindow* (*gtk_widget_get_window)(GtkWidget *widget) = nullptr; inline void (*gtk_widget_realize)(GtkWidget *widget) = nullptr; -inline gboolean (*gtk_widget_hide_on_delete)(GtkWidget *widget) = nullptr; inline void (*gtk_widget_destroy)(GtkWidget *widget) = nullptr; inline GtkClipboard* (*gtk_clipboard_get)(GdkAtom selection) = nullptr; -inline void (*gtk_clipboard_store)(GtkClipboard *clipboard) = nullptr; inline GtkSelectionData* (*gtk_clipboard_wait_for_contents)(GtkClipboard *clipboard, GdkAtom target) = nullptr; inline GdkPixbuf* (*gtk_clipboard_wait_for_image)(GtkClipboard *clipboard) = nullptr; inline gboolean (*gtk_selection_data_targets_include_image)(const GtkSelectionData *selection_data, gboolean writable) = nullptr; inline void (*gtk_selection_data_free)(GtkSelectionData *data) = nullptr; -inline GType (*gtk_file_chooser_get_type)(void) G_GNUC_CONST = nullptr; -inline GtkWidget* (*gtk_file_chooser_dialog_new)(const gchar *title, GtkWindow *parent, GtkFileChooserAction action, const gchar *first_button_text, ...) G_GNUC_NULL_TERMINATED = nullptr; -inline gboolean (*gtk_file_chooser_set_current_folder)(GtkFileChooser *chooser, const gchar *filename) = nullptr; -inline gchar* (*gtk_file_chooser_get_current_folder)(GtkFileChooser *chooser) = nullptr; -inline void (*gtk_file_chooser_set_current_name)(GtkFileChooser *chooser, const gchar *name) = nullptr; -inline gboolean (*gtk_file_chooser_select_filename)(GtkFileChooser *chooser, const gchar *filename) = nullptr; -inline GSList* (*gtk_file_chooser_get_filenames)(GtkFileChooser *chooser) = nullptr; -inline void (*gtk_file_chooser_set_filter)(GtkFileChooser *chooser, GtkFileFilter *filter) = nullptr; -inline GtkFileFilter* (*gtk_file_chooser_get_filter)(GtkFileChooser *chooser) = nullptr; -inline GType (*gtk_window_get_type)(void) G_GNUC_CONST = nullptr; -inline void (*gtk_window_set_title)(GtkWindow *window, const gchar *title) = nullptr; -inline void (*gtk_file_chooser_set_local_only)(GtkFileChooser *chooser, gboolean local_only) = nullptr; -inline void (*gtk_file_chooser_set_action)(GtkFileChooser *chooser, GtkFileChooserAction action) = nullptr; -inline void (*gtk_file_chooser_set_select_multiple)(GtkFileChooser *chooser, gboolean select_multiple) = nullptr; -inline void (*gtk_file_chooser_set_do_overwrite_confirmation)(GtkFileChooser *chooser, gboolean do_overwrite_confirmation) = nullptr; -inline GType (*gtk_dialog_get_type)(void) G_GNUC_CONST = nullptr; -inline GtkWidget* (*gtk_dialog_get_widget_for_response)(GtkDialog *dialog, gint response_id) = nullptr; -inline GType (*gtk_button_get_type)(void) G_GNUC_CONST = nullptr; -inline void (*gtk_button_set_label)(GtkButton *button, const gchar *label) = nullptr; -inline void (*gtk_file_chooser_remove_filter)(GtkFileChooser *chooser, GtkFileFilter *filter) = nullptr; -inline void (*gtk_file_filter_set_name)(GtkFileFilter *filter, const gchar *name) = nullptr; -inline void (*gtk_file_filter_add_pattern)(GtkFileFilter *filter, const gchar *pattern) = nullptr; -inline void (*gtk_file_chooser_add_filter)(GtkFileChooser *chooser, GtkFileFilter *filter) = nullptr; -inline void (*gtk_file_chooser_set_preview_widget)(GtkFileChooser *chooser, GtkWidget *preview_widget) = nullptr; -inline gchar* (*gtk_file_chooser_get_preview_filename)(GtkFileChooser *chooser) = nullptr; -inline void (*gtk_file_chooser_set_preview_widget_active)(GtkFileChooser *chooser, gboolean active) = nullptr; -inline GtkFileFilter* (*gtk_file_filter_new)(void) = nullptr; -inline GType (*gtk_image_get_type)(void) G_GNUC_CONST = nullptr; -inline GtkWidget* (*gtk_image_new)(void) = nullptr; -inline void (*gtk_image_set_from_pixbuf)(GtkImage *image, GdkPixbuf *pixbuf) = nullptr; inline GType (*gtk_app_chooser_get_type)(void) G_GNUC_CONST = nullptr; inline GtkWidget* (*gtk_app_chooser_dialog_new)(GtkWindow *parent, GtkDialogFlags flags, GFile *file) = nullptr; inline GAppInfo* (*gtk_app_chooser_get_app_info)(GtkAppChooser *self) = nullptr; -inline void (*gdk_window_set_modal_hint)(GdkWindow *window, gboolean modal) = nullptr; -inline void (*gdk_window_focus)(GdkWindow *window, guint32 timestamp) = nullptr; -inline gint (*gtk_dialog_run)(GtkDialog *dialog) = nullptr; inline GdkAtom (*gdk_atom_intern)(const gchar *atom_name, gboolean only_if_exists) = nullptr; inline GdkDisplay* (*gdk_display_get_default)(void) = nullptr; inline GdkMonitor* (*gdk_display_get_monitor)(GdkDisplay *display, int monitor_num) = nullptr; inline GdkMonitor* (*gdk_display_get_primary_monitor)(GdkDisplay *display) = nullptr; inline int (*gdk_monitor_get_scale_factor)(GdkMonitor *monitor) = nullptr; -inline GdkPixbuf* (*gdk_pixbuf_new_from_file_at_size)(const gchar *filename, int width, int height, GError **error) = nullptr; inline gboolean (*gdk_pixbuf_get_has_alpha)(const GdkPixbuf *pixbuf) = nullptr; inline guchar* (*gdk_pixbuf_get_pixels)(const GdkPixbuf *pixbuf) = nullptr; inline int (*gdk_pixbuf_get_width)(const GdkPixbuf *pixbuf) = nullptr;