2021-01-10 03:51:38 +00:00
|
|
|
/*
|
|
|
|
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
|
|
|
|
*/
|
2021-03-06 22:29:13 +00:00
|
|
|
#include "platform/linux/linux_gtk_open_with_dialog.h"
|
2021-01-10 03:51:38 +00:00
|
|
|
|
|
|
|
#include "platform/linux/linux_gtk_integration_p.h"
|
|
|
|
#include "platform/linux/linux_gdk_helper.h"
|
|
|
|
|
2021-06-24 05:03:14 +00:00
|
|
|
#include <giomm.h>
|
2021-01-10 03:51:38 +00:00
|
|
|
|
|
|
|
namespace Platform {
|
|
|
|
namespace File {
|
|
|
|
namespace internal {
|
|
|
|
namespace {
|
|
|
|
|
|
|
|
using namespace Platform::Gtk;
|
|
|
|
|
2021-06-24 05:03:14 +00:00
|
|
|
struct GtkWidgetDeleter {
|
|
|
|
void operator()(GtkWidget *widget) {
|
|
|
|
gtk_widget_destroy(widget);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2021-03-06 22:29:13 +00:00
|
|
|
bool Supported() {
|
2021-05-10 08:53:34 +00:00
|
|
|
return (gtk_app_chooser_dialog_new != nullptr)
|
2021-01-10 03:51:38 +00:00
|
|
|
&& (gtk_app_chooser_get_app_info != nullptr)
|
|
|
|
&& (gtk_app_chooser_get_type != nullptr)
|
|
|
|
&& (gtk_widget_get_window != nullptr)
|
|
|
|
&& (gtk_widget_realize != nullptr)
|
|
|
|
&& (gtk_widget_show != nullptr)
|
|
|
|
&& (gtk_widget_destroy != nullptr);
|
|
|
|
}
|
|
|
|
|
2021-07-03 01:48:35 +00:00
|
|
|
} // namespace
|
|
|
|
|
|
|
|
class GtkOpenWithDialog::Private {
|
2021-01-10 03:51:38 +00:00
|
|
|
public:
|
2021-07-03 01:48:35 +00:00
|
|
|
Private(
|
2021-06-22 23:20:40 +00:00
|
|
|
const QString &parent,
|
|
|
|
const QString &filepath);
|
2021-01-10 03:51:38 +00:00
|
|
|
|
|
|
|
private:
|
2021-07-03 01:48:35 +00:00
|
|
|
friend class GtkOpenWithDialog;
|
|
|
|
|
|
|
|
static void handleResponse(Private *dialog, int responseId);
|
2021-01-10 03:51:38 +00:00
|
|
|
|
2021-06-24 05:03:14 +00:00
|
|
|
const Glib::RefPtr<Gio::File> _file;
|
|
|
|
const std::unique_ptr<GtkWidget, GtkWidgetDeleter> _gtkWidget;
|
2021-07-03 01:48:35 +00:00
|
|
|
rpl::event_stream<bool> _responseStream;
|
2021-01-10 03:51:38 +00:00
|
|
|
};
|
|
|
|
|
2021-07-03 01:48:35 +00:00
|
|
|
GtkOpenWithDialog::Private::Private(
|
2021-06-22 23:20:40 +00:00
|
|
|
const QString &parent,
|
|
|
|
const QString &filepath)
|
2021-06-24 05:03:14 +00:00
|
|
|
: _file(Gio::File::create_for_path(filepath.toStdString()))
|
2021-01-10 03:51:38 +00:00
|
|
|
, _gtkWidget(gtk_app_chooser_dialog_new(
|
|
|
|
nullptr,
|
|
|
|
GTK_DIALOG_MODAL,
|
2021-06-24 05:03:14 +00:00
|
|
|
_file->gobj())) {
|
2021-01-10 03:51:38 +00:00
|
|
|
g_signal_connect_swapped(
|
2021-06-24 05:03:14 +00:00
|
|
|
_gtkWidget.get(),
|
2021-01-10 03:51:38 +00:00
|
|
|
"response",
|
|
|
|
G_CALLBACK(handleResponse),
|
|
|
|
this);
|
|
|
|
|
2021-06-24 05:03:14 +00:00
|
|
|
gtk_widget_realize(_gtkWidget.get());
|
2021-01-10 03:51:38 +00:00
|
|
|
|
2021-06-22 23:20:40 +00:00
|
|
|
Platform::internal::GdkSetTransientFor(
|
|
|
|
gtk_widget_get_window(_gtkWidget.get()),
|
|
|
|
parent);
|
2021-01-10 03:51:38 +00:00
|
|
|
|
2021-06-24 05:03:14 +00:00
|
|
|
gtk_widget_show(_gtkWidget.get());
|
2021-01-10 03:51:38 +00:00
|
|
|
}
|
|
|
|
|
2021-07-03 01:48:35 +00:00
|
|
|
void GtkOpenWithDialog::Private::handleResponse(Private *dialog, int responseId) {
|
2021-06-24 05:03:14 +00:00
|
|
|
Glib::RefPtr<Gio::AppInfo> chosenAppInfo;
|
2021-06-22 23:20:40 +00:00
|
|
|
bool result = true;
|
2021-01-10 03:51:38 +00:00
|
|
|
|
|
|
|
switch (responseId) {
|
|
|
|
case GTK_RESPONSE_OK:
|
2021-06-24 05:03:14 +00:00
|
|
|
chosenAppInfo = Glib::wrap(gtk_app_chooser_get_app_info(
|
|
|
|
GTK_APP_CHOOSER(dialog->_gtkWidget.get())));
|
2021-01-10 03:51:38 +00:00
|
|
|
|
|
|
|
if (chosenAppInfo) {
|
2021-06-24 05:03:14 +00:00
|
|
|
try {
|
|
|
|
chosenAppInfo->launch_uri(dialog->_file->get_uri());
|
|
|
|
} catch (...) {
|
|
|
|
}
|
|
|
|
chosenAppInfo = {};
|
2021-01-10 03:51:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
case GTK_RESPONSE_CANCEL:
|
|
|
|
case GTK_RESPONSE_DELETE_EVENT:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2021-06-22 23:20:40 +00:00
|
|
|
result = false;
|
2021-01-10 03:51:38 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2021-07-03 01:48:35 +00:00
|
|
|
dialog->_responseStream.fire_copy(result);
|
2021-01-10 03:51:38 +00:00
|
|
|
}
|
|
|
|
|
2021-07-03 01:48:35 +00:00
|
|
|
GtkOpenWithDialog::GtkOpenWithDialog(
|
|
|
|
const QString &parent,
|
|
|
|
const QString &filepath)
|
|
|
|
: _private(std::make_unique<Private>(parent, filepath)) {
|
|
|
|
}
|
2021-01-10 03:51:38 +00:00
|
|
|
|
2021-07-03 01:48:35 +00:00
|
|
|
GtkOpenWithDialog::~GtkOpenWithDialog() = default;
|
|
|
|
|
|
|
|
rpl::producer<bool> GtkOpenWithDialog::response() {
|
|
|
|
return _private->_responseStream.events();
|
|
|
|
}
|
|
|
|
|
|
|
|
std::unique_ptr<GtkOpenWithDialog> CreateGtkOpenWithDialog(
|
2021-06-22 23:20:40 +00:00
|
|
|
const QString &parent,
|
|
|
|
const QString &filepath) {
|
2021-03-06 22:29:13 +00:00
|
|
|
if (!Supported()) {
|
2021-07-03 01:48:35 +00:00
|
|
|
return nullptr;
|
2021-01-10 03:51:38 +00:00
|
|
|
}
|
|
|
|
|
2021-07-03 01:48:35 +00:00
|
|
|
return std::make_unique<GtkOpenWithDialog>(parent, filepath);
|
2021-01-10 03:51:38 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace internal
|
|
|
|
} // namespace File
|
|
|
|
} // namespace Platform
|