42 #include <gio/gdesktopappinfo.h> 44 #include <gdk/gdkkeysyms.h> 45 #include <glib/gi18n.h> 71 #define RM_GET_OBJECT(object_name) gtk_builder_get_object(remminamain->builder, object_name) 88 "x-scheme-handler/rdp",
89 "x-scheme-handler/spice",
90 "x-scheme-handler/vnc",
91 "x-scheme-handler/remmina",
92 "application/x-remmina",
128 {
"text/uri-list", 0, 1 }
133 "RDP",
"VNC",
"SSH",
"NX",
"SPICE",
"X2GO" 141 TRACE_CALL(__func__);
142 if ((gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(remminamain->
window))) & GDK_WINDOW_STATE_MAXIMIZED) == 0) {
152 TRACE_CALL(__func__);
166 TRACE_CALL(__func__);
182 TRACE_CALL(__func__);
183 if (!remminamain || !remminamain->
window)
195 TRACE_CALL(__func__);
199 gtk_widget_destroy(GTK_WIDGET(remminamain->
window));
201 g_object_unref(remminamain->
builder);
209 g_free(remminamain->
priv);
220 TRACE_CALL(__func__);
227 TRACE_CALL(__func__);
237 TRACE_CALL(__func__);
242 return G_SOURCE_REMOVE;
250 TRACE_CALL(__func__);
254 remminamain->
window = NULL;
263 TRACE_CALL(__func__);
274 GtkBuilder *dlgbuilder = NULL;
278 static gboolean shown_once = FALSE;
279 gboolean need_snap_interface_connections = FALSE;
288 g_print(
"Remmina is compiled as a SNAP package.\n");
290 if (remmina_secret_plugin == NULL) {
291 g_print(
" but we can’t find the secret plugin inside the SNAP.\n");
292 need_snap_interface_connections = TRUE;
295 g_print(
" but we can’t access a secret service. Secret service or SNAP interface connection is missing.\n");
296 need_snap_interface_connections = TRUE;
302 dsa = GTK_WIDGET(gtk_builder_get_object(dlgbuilder,
"dontshowagain"));
305 dlg = GTK_WIDGET(gtk_builder_get_object(dlgbuilder,
"SnapInfoDlg"));
307 gtk_window_set_transient_for(GTK_WINDOW(dlg), parent);
308 gtk_builder_connect_signals(dlgbuilder, NULL);
309 result = gtk_dialog_run(GTK_DIALOG(dlg));
314 gtk_widget_destroy(dlg);
315 g_object_unref(dlgbuilder);
323 gboolean path_currently_selected, gpointer user_data)
325 TRACE_CALL(__func__);
330 if (path_currently_selected)
333 if (!gtk_tree_model_get_iter(model, &iter, path))
338 gtk_tree_model_get(model, &iter,
343 context_id = gtk_statusbar_get_context_id(remminamain->
statusbar_main,
"status");
357 TRACE_CALL(__func__);
361 store = GTK_LIST_STORE(user_data);
365 gtk_list_store_append(store, &iter);
366 gtk_list_store_set(store, &iter,
382 TRACE_CALL(__func__);
390 iter = g_new0(GtkTreeIter, 1);
391 gtk_tree_store_append(store, iter, parent);
392 gtk_tree_store_set(store, iter,
401 for (child = g_node_first_child(node); child; child = g_node_next_sibling(child))
409 TRACE_CALL(__func__);
419 TRACE_CALL(__func__);
422 gchar *group, *filename;
430 if (filename == NULL) {
432 path = gtk_tree_model_get_path(tree, iter);
434 gtk_tree_path_free(path);
436 if (gtk_tree_model_iter_children(tree, &child, iter))
442 ret = gtk_tree_model_iter_next(tree, iter);
448 TRACE_CALL(__func__);
457 TRACE_CALL(__func__);
459 gchar *group, *filename;
466 match = (filename == NULL && g_strcmp0(group, match_group) == 0);
471 if (gtk_tree_model_iter_children(tree, &child, iter)) {
474 memcpy(iter, &child,
sizeof(GtkTreeIter));
478 ret = gtk_tree_model_iter_next(tree, iter);
485 TRACE_CALL(__func__);
486 GtkTreeIter iter, child;
489 gchar *datetime = NULL;
491 store = GTK_TREE_STORE(user_data);
494 if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter))
500 gtk_tree_store_append(store, &child, (found ? &iter : NULL));
501 gtk_tree_store_set(store, &child,
517 TRACE_CALL(__func__);
521 gtk_tree_sortable_get_sort_column_id(sortable, &columnid, &order);
529 TRACE_CALL(__func__);
531 gchar *protocol, *name, *labels, *group, *server, *plugin, *date, *s;
532 gboolean result = TRUE;
535 if (text && text[0]) {
536 gtk_tree_model_get(model, iter,
545 if (g_strcmp0(protocol,
"folder-symbolic") != 0) {
546 s = g_ascii_strdown(name ? name :
"", -1);
549 s = g_ascii_strdown(group ? group :
"", -1);
552 s = g_ascii_strdown(server ? server :
"", -1);
555 s = g_ascii_strdown(plugin ? plugin :
"", -1);
558 s = g_ascii_strdown(date ? date :
"", -1);
561 result = (strstr(name, text) || strstr(group, text) || strstr(server, text) || strstr(plugin, text) || strstr(date, text));
565 s = g_ascii_strdown(labels ? labels :
"", -1);
569 if (strlen(labels) > 0) {
570 gboolean labels_result = TRUE;
571 gchar **labels_array = g_strsplit(labels,
",", -1);
572 gchar **text_array = g_strsplit(text,
",", -1);
574 for (
int t = 0; (NULL != text_array[t]); t++) {
575 if (0 == strlen(text_array[t])) {
579 gboolean text_result = FALSE;
581 for (
int l = 0; (NULL != labels_array[l]); l++) {
582 if (0 == strlen(labels_array[l])) {
586 text_result = (text_result || strstr(labels_array[l], text_array[t]));
593 labels_result = (labels_result && text_result);
595 if (!labels_result) {
600 result = (result || labels_result);
602 g_strfreev(labels_array);
603 g_strfreev(text_array);
620 TRACE_CALL(__func__);
623 gchar *item_filename;
631 cmp = g_strcmp0(item_filename, filename);
632 g_free(item_filename);
634 gtk_tree_selection_select_iter(gtk_tree_view_get_selection(remminamain->
tree_files_list),
637 gtk_tree_view_scroll_to_cell(remminamain->
tree_files_list, path, NULL, TRUE, 0.5, 0.0);
638 gtk_tree_path_free(path);
648 TRACE_CALL(__func__);
653 gboolean always_show_notes;
654 char *save_selected_filename;
655 GtkTreeModel *newmodel;
656 const gchar *neticon;
657 const gchar *connection_tooltip;
676 switch (view_file_mode) {
679 newmodel = GTK_TREE_MODEL(gtk_tree_store_new(9, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING));
691 newmodel = GTK_TREE_MODEL(gtk_list_store_new(9, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING));
701 if (!always_show_notes){
716 gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(remminamain->
priv->
file_model_sort),
724 if (save_selected_filename) {
726 g_free(save_selected_filename);
732 gtk_widget_set_tooltip_text(GTK_WIDGET(label),
733 _(
"The latest successful connection attempt, or a pre-computed date"));
735 g_snprintf(buf,
sizeof(buf), ngettext(
"Total %i item.",
"Total %i items.", items_count), items_count);
736 context_id = gtk_statusbar_get_context_id(remminamain->
statusbar_main,
"status");
742 neticon = g_strdup(
"network-transmit-receive-symbolic");
743 connection_tooltip = g_strdup(_(
"Network status: fully online"));
745 neticon = g_strdup(
"network-offline-symbolic");
746 connection_tooltip = g_strdup(_(
"Network status: offline"));
751 GIcon *icon = g_themed_icon_new (neticon);
752 remminamain->
network_icon = gtk_image_new_from_gicon (icon, GTK_ICON_SIZE_BUTTON);
753 gtk_widget_set_tooltip_text (remminamain->
network_icon, connection_tooltip);
755 g_object_unref (icon);
764 TRACE_CALL(__func__);
770 TRACE_CALL(__func__);
779 if (remminafile == NULL)
798 TRACE_CALL(__func__);
807 TRACE_CALL(__func__);
816 TRACE_CALL(__func__);
819 const gchar *username;
822 const gchar *gatewayusername;
823 const gchar *gatewaydomain;
825 username = domain = group = gatewayusername = gatewaydomain =
"";
836 if (remminafile != NULL) {
847 if (remminafile != NULL)
853 TRACE_CALL(__func__);
865 gtk_window_set_transient_for(GTK_WINDOW(widget), remminamain->
window);
866 gtk_widget_show(widget);
872 TRACE_CALL(__func__);
873 if (event->keyval == GDK_KEY_Escape) {
875 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(RM_GET_OBJECT(
"search_toggle")), FALSE);
883 TRACE_CALL(__func__);
884 if (gtk_tree_view_row_expanded(tree, path))
885 gtk_tree_view_collapse_row(tree, path);
887 gtk_tree_view_expand_row(tree, path, FALSE);
912 TRACE_CALL(__func__);
938 gtk_window_set_transient_for(GTK_WINDOW(widget), remminamain->
window);
939 gtk_widget_show(widget);
948 TRACE_CALL(__func__);
969 gtk_window_set_transient_for(GTK_WINDOW(widget), remminamain->
window);
970 gtk_widget_show(widget);
979 TRACE_CALL(__func__);
998 dialog = gtk_message_dialog_new(remminamain->
window, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
1000 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_YES) {
1003 g_free(delfilename), delfilename = NULL;
1007 gtk_widget_destroy(dialog);
1013 TRACE_CALL(__func__);
1015 GtkTreeSelection *sel = gtk_tree_view_get_selection(remminamain->
tree_files_list);
1016 GtkTreeModel *model = gtk_tree_view_get_model(remminamain->
tree_files_list);
1017 GList *list = gtk_tree_selection_get_selected_rows(sel, &model);
1018 gchar *file_to_delete;
1020 dialog = gtk_message_dialog_new(remminamain->
window, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
1021 _(
"Are you sure you want to delete the selected files?"));
1024 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_YES) {
1026 GtkTreePath *path = list->data;
1029 if (!gtk_tree_model_get_iter(model, &iter, path)) {
1030 GtkWidget *dialog_warning;
1031 dialog_warning = gtk_message_dialog_new(remminamain->
window, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_OK,
1032 _(
"Failed to delete files!"));
1033 gtk_dialog_run(GTK_DIALOG(dialog_warning));
1034 gtk_widget_destroy(dialog_warning);
1035 gtk_widget_destroy(dialog);
1040 gtk_tree_model_get(model, &iter,
1056 gchar *delfilename = g_strdup(file_to_delete);
1058 g_free(delfilename), delfilename = NULL;
1061 list = g_list_next(list);
1065 gtk_widget_destroy(dialog);
1071 TRACE_CALL(__func__);
1072 GVariant *v = g_variant_new(
"i", 0);
1079 GtkSettings *settings;
1080 settings = gtk_settings_get_default();
1083 gtk_toggle_button_set_active(remminamain->
search_toggle, FALSE);
1086 gtk_toggle_button_set_active(remminamain->
search_toggle, TRUE);
1093 TRACE_CALL(__func__);
1095 REMMINA_DEBUG(
"Opening the preferences");
1099 REMMINA_DEBUG(
"Parameter passed to preferences of type %s", g_variant_get_type_string(param));
1100 tab_num = g_variant_get_int32(param);
1101 REMMINA_DEBUG(
"We got a parameter for the preferences: %d", tab_num);
1112 gtk_widget_show_all(widget);
1117 TRACE_CALL(__func__);
1119 g_autoptr(GError) error = NULL;
1120 GDesktopAppInfo *desktop_info;
1121 GAppInfo *info = NULL;
1122 g_autofree gchar *
id = g_strconcat(REMMINA_APP_ID,
".desktop", NULL);
1125 desktop_info = g_desktop_app_info_new(
id);
1129 info = G_APP_INFO(desktop_info);
1133 g_warning(
"Failed to set '%s' as the default application for secondary content type '%s': %s",
1136 g_debug(
"Set '%s' as the default application for '%s'",
1137 g_app_info_get_name(info),
1146 TRACE_CALL(__func__);
1147 g_debug(
"Quit intercept");
1163 GtkWindow *mainwindow;
1164 gboolean visible = gtk_entry_get_visibility(GTK_ENTRY(widget));
1171 gtk_entry_set_visibility(GTK_ENTRY(widget), FALSE);
1172 gtk_entry_set_icon_from_icon_name(GTK_ENTRY(widget), GTK_ENTRY_ICON_SECONDARY,
"org.remmina.Remmina-password-reveal-symbolic");
1174 gtk_entry_set_visibility(GTK_ENTRY(widget), TRUE);
1175 gtk_entry_set_icon_from_icon_name(GTK_ENTRY(widget), GTK_ENTRY_ICON_SECONDARY,
"org.remmina.Remmina-password-conceal-symbolic");
1181 TRACE_CALL(__func__);
1190 err = g_string_new(NULL);
1192 for (element = files; element; element = element->next) {
1193 path = (gchar *)element->data;
1200 g_string_append(err, path);
1201 g_string_append_c(err,
'\n');
1209 g_slist_free(files);
1212 dlg = gtk_message_dialog_new(remminamain->
window, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
1213 _(
"Unable to import:\n%s"), err->str);
1214 g_signal_connect(G_OBJECT(dlg),
"response", G_CALLBACK(gtk_widget_destroy), NULL);
1215 gtk_widget_show(dlg);
1217 g_string_free(err, TRUE);
1224 TRACE_CALL(__func__);
1227 if (response_id == GTK_RESPONSE_ACCEPT) {
1228 files = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
1231 gtk_widget_destroy(GTK_WIDGET(dialog));
1236 TRACE_CALL(__func__);
1239 dialog = gtk_file_chooser_dialog_new(_(
"Import"), remminamain->
window, GTK_FILE_CHOOSER_ACTION_OPEN,
"Import",
1240 GTK_RESPONSE_ACCEPT, NULL);
1241 gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
1243 gtk_widget_show(dialog);
1248 TRACE_CALL(__func__);
1257 if (remminafile == NULL)
1262 GTK_FILE_CHOOSER_ACTION_SAVE, _(
"_Save"), GTK_RESPONSE_ACCEPT, NULL);
1263 if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
1264 plugin->
export_func(plugin, remminafile, gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)));
1265 gtk_widget_destroy(dialog);
1267 dialog = gtk_message_dialog_new(remminamain->
window, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
1268 _(
"This protocol does not support exporting."));
1269 g_signal_connect(G_OBJECT(dialog),
"response", G_CALLBACK(gtk_widget_destroy), NULL);
1270 gtk_widget_show(dialog);
1277 TRACE_CALL(__func__);
1283 TRACE_CALL(__func__);
1284 GtkSettings *settings;
1286 settings = gtk_settings_get_default();
1299 TRACE_CALL(__func__);
1300 g_app_info_launch_default_for_uri(
"https://www.remmina.org", NULL, NULL);
1305 TRACE_CALL(__func__);
1306 g_app_info_launch_default_for_uri(
"https://gitlab.com/Remmina/Remmina/wikis/home", NULL, NULL);
1311 TRACE_CALL(__func__);
1312 g_app_info_launch_default_for_uri(
"https://remmina.org/community", NULL, NULL);
1317 TRACE_CALL(__func__);
1318 g_app_info_launch_default_for_uri(
"https://www.remmina.org/donations", NULL, NULL);
1323 TRACE_CALL(__func__);
1329 TRACE_CALL(__func__);
1338 if (!isspace((
unsigned char)*s))
1347 TRACE_CALL(__func__);
1350 gchar *server_trimmed;
1364 if (g_hostname_to_ascii(server) == NULL)
1370 if (g_strrstr(server,
"/") != NULL)
1378 server_trimmed = g_strdup(server);
1379 g_strstrip(server_trimmed);
1380 gchar **strings = g_strsplit(server_trimmed,
":", 2);
1382 if (strings[0] != NULL)
1383 if (g_hostname_is_ip_address(strings[0]))
1384 g_stpcpy(server, server_trimmed);
1391 g_free(server_trimmed);
1401 TRACE_CALL(__func__);
1416 TRACE_CALL(__func__);
1422 TRACE_CALL(__func__);
1423 REMMINA_DEBUG(
"Search toggle triggered");
1425 gboolean toggle_status = gtk_toggle_button_get_active(remminamain->
search_toggle);
1427 gtk_search_bar_set_search_mode(remminamain->
search_bar, toggle_status);
1428 if (toggle_status) {
1429 REMMINA_DEBUG(
"Search toggle is active");
1432 REMMINA_DEBUG(
"Search toggle is not active, focus is tree_files_list");
1439 TRACE_CALL(__func__);
1440 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(remminamain->
search_toggle), TRUE);
1445 TRACE_CALL(__func__);
1452 TRACE_CALL(__func__);
1470 TRACE_CALL(__func__);
1471 if (event->button == MOUSE_BUTTON_RIGHT) {
1473 #if GTK_CHECK_VERSION(3, 22, 0) 1475 if (gtk_tree_selection_count_selected_rows(gtk_tree_view_get_selection(remminamain->
tree_files_list)) > 1) {
1477 return GDK_EVENT_STOP;
1480 gtk_menu_popup_at_pointer(GTK_MENU(remminamain->
menu_popup), (GdkEvent *)event);
1483 gtk_menu_popup(remminamain->
menu_popup, NULL, NULL, NULL, NULL, event->button, event->time);
1493 TRACE_CALL(__func__);
1494 if (event->keyval == GDK_KEY_Menu) {
1495 #if GTK_CHECK_VERSION(3, 22, 0) 1496 gtk_menu_popup_at_widget(GTK_MENU(remminamain->
menu_popup), widget,
1497 GDK_GRAVITY_CENTER, GDK_GRAVITY_CENTER,
1500 gtk_menu_popup(remminamain->
menu_popup, NULL, NULL, NULL, NULL, 0, event->time);
1508 TRACE_CALL(__func__);
1509 if (icon_pos == GTK_ENTRY_ICON_SECONDARY)
1510 gtk_entry_set_text(entry,
"");
1515 TRACE_CALL(__func__);
1534 GtkSelectionData *data, guint info, guint time, gpointer user_data)
1536 TRACE_CALL(__func__);
1538 GSList *files = NULL;
1541 uris = g_uri_list_extract_uris((
const gchar *)gtk_selection_data_get_data(data));
1542 for (i = 0; uris[i]; i++) {
1543 if (strncmp(uris[i],
"file://", 7) != 0)
1545 files = g_slist_append(files, g_strdup(uris[i] + 7));
1554 TRACE_CALL(__func__);
1556 GtkWidget *menuitem = gtk_menu_item_new_with_label(plugin->
description);
1558 gtk_widget_show(menuitem);
1559 gtk_menu_shell_append(GTK_MENU_SHELL(remminamain->
menu_popup_full), menuitem);
1560 g_signal_connect(G_OBJECT(menuitem),
"activate", G_CALLBACK(tool_plugin->
exec_func), tool_plugin);
1566 TRACE_CALL(__func__);
1573 TRACE_CALL(__func__);
1574 int i, qcp_idx, qcp_actidx;
1576 GtkSettings *settings;
1578 REMMINA_DEBUG(
"Initializing the Remmina main window");
1580 settings = gtk_settings_get_default();
1583 REMMINA_DEBUG (
"Initializing monitor");
1588 gtk_window_set_title(remminamain->
window, _(
"Remmina Remote Desktop Client"));
1590 gtk_window_set_title(remminamain->
window, _(
"Remmina Kiosk"));
1594 gtk_window_maximize(remminamain->
window);
1598 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(RM_GET_OBJECT(
"search_toggle")), FALSE);
1604 qcp_idx = qcp_actidx = 0;
1610 qcp_actidx = qcp_idx;
1621 gtk_tree_selection_set_select_function(
1638 g_object_set_data(G_OBJECT(remminamain->
window),
"tag",
"remmina-main-window");
1645 TRACE_CALL(__func__);
1654 TRACE_CALL(__func__);
1655 GSimpleActionGroup *actions;
1656 GtkAccelGroup *accel_group = NULL;
1662 remminamain->
window = GTK_WINDOW(RM_GET_OBJECT(
"RemminaMain"));
1664 gtk_window_set_position(remminamain->
window, GTK_WIN_POS_CENTER_ALWAYS);
1665 gtk_window_set_default_size(remminamain->
window, 800, 400);
1666 gtk_window_set_resizable(remminamain->
window, FALSE);
1669 remminamain->
button_new = GTK_BUTTON(RM_GET_OBJECT(
"button_new"));
1671 gtk_widget_set_sensitive(GTK_WIDGET(remminamain->
button_new), FALSE);
1673 remminamain->
search_toggle = GTK_TOGGLE_BUTTON(RM_GET_OBJECT(
"search_toggle"));
1674 remminamain->
search_bar = GTK_SEARCH_BAR(RM_GET_OBJECT(
"search_bar"));
1676 remminamain->
view_toggle_button = GTK_TOGGLE_BUTTON(RM_GET_OBJECT(
"view_toggle_button"));
1681 remminamain->
menu_popup = GTK_MENU(RM_GET_OBJECT(
"menu_popup"));
1682 remminamain->
menu_header_button = GTK_MENU_BUTTON(RM_GET_OBJECT(
"menu_header_button"));
1683 remminamain->
menu_popup_full = GTK_MENU(RM_GET_OBJECT(
"menu_popup_full"));
1686 gtk_widget_set_sensitive(GTK_WIDGET(remminamain->
menu_popup_full), FALSE);
1699 remminamain->
tree_files_list = GTK_TREE_VIEW(RM_GET_OBJECT(
"tree_files_list"));
1707 remminamain->
statusbar_main = GTK_STATUSBAR(RM_GET_OBJECT(
"statusbar_main"));
1712 actions = g_simple_action_group_new();
1714 gtk_widget_insert_action_group(GTK_WIDGET(remminamain->
window),
"app", G_ACTION_GROUP(actions));
1716 gtk_widget_insert_action_group(GTK_WIDGET(remminamain->
window),
"main", G_ACTION_GROUP(actions));
1717 g_object_unref(actions);
1719 accel_group = gtk_accel_group_new();
1720 gtk_window_add_accel_group(remminamain->
window, accel_group);
1721 gtk_accel_group_connect(accel_group, GDK_KEY_Q, GDK_CONTROL_MASK, 0,
1724 gtk_accel_group_connect(accel_group, GDK_KEY_P, GDK_CONTROL_MASK, 0,
1726 gtk_accel_group_connect(accel_group, GDK_KEY_F, GDK_CONTROL_MASK, 0,
1730 gtk_builder_connect_signals(remminamain->
builder, NULL);
1733 return GTK_WIDGET(remminamain->
window);
1740 if (!remminamain->
priv)
1744 remminamain->
window = GTK_WINDOW(RM_GET_OBJECT(
"RemminaMain"));
1745 return remminamain->
window;
1758 if (remminamain->
window) {
1759 dialog = gtk_message_dialog_new(remminamain->
window, GTK_DIALOG_MODAL, msg, buttons,
"%s", message);
1760 gtk_dialog_run(GTK_DIALOG(dialog));
1761 gtk_widget_destroy(dialog);
1768 if (remminamain->
window) {
1769 dialog = gtk_message_dialog_new(remminamain->
window, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE,
1770 message, g_get_application_name());
1771 gtk_dialog_run(GTK_DIALOG(dialog));
1772 gtk_widget_destroy(dialog);
G_BEGIN_DECLS struct _RemminaGroupData RemminaGroupData
RemminaFile * remmina_file_load(const gchar *filename)
static RemminaSecretPlugin * remmina_secret_plugin
void remmina_log_start(void)
static GActionEntry main_actions[]
void remmina_file_free(RemminaFile *remminafile)
GtkToggleButton * search_toggle
const gchar * remmina_file_get_string(RemminaFile *remminafile, const gchar *setting)
GtkRadioMenuItem * menuitem_view_mode_list
static void remmina_main_load_file_tree_callback(RemminaFile *remminafile, gpointer user_data)
void remmina_main_on_action_help_homepage(GSimpleAction *action, GVariant *param, gpointer data)
static void remmina_main_show_snap_welcome()
GtkWindow * remmina_main_get_window()
gchar * selected_filename
GtkTreeModel * file_model
static void remmina_main_save_expanded_group(void)
void remmina_main_reload_preferences()
const gchar * remmina_file_get_filename(RemminaFile *remminafile)
void remmina_main_on_action_connection_connect(GSimpleAction *action, GVariant *param, gpointer data)
typedefG_BEGIN_DECLS struct _RemminaFile RemminaFile
GtkRadioMenuItem * menuitem_view_mode_tree
GtkTreeViewColumn * column_files_list_name
const gchar * export_hints
void remmina_plugin_manager_for_each_plugin(RemminaPluginType type, RemminaPluginFunc func, gpointer data)
GtkMenu * menu_popup_delete_rc
gchar * last_quickconnect_protocol
gboolean remmina_main_file_list_on_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
RemminaFile *(* import_func)(struct _RemminaFilePlugin *instance, const gchar *from_file)
static gboolean remmina_main_filter_visible_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
gboolean remmina_network_monitor_status(RemminaMonitor *rm_monitor)
RemminaFilePlugin * remmina_plugin_manager_get_export_file_handler(RemminaFile *remminafile)
void remmina_file_manager_free_group_tree(GNode *node)
RemminaFilePlugin * remmina_plugin_manager_get_import_file_handler(const gchar *file)
static gboolean remmina_main_search_key_event(GtkWidget *search_entry, GdkEventKey *event, gpointer user_data)
void remmina_main_on_action_tools_import(GSimpleAction *action, GVariant *param, gpointer data)
RemminaMonitor * remmina_network_monitor_new()
RemminaSecretPlugin * remmina_plugin_manager_get_secret_plugin(void)
static void remmina_main_save_size(void)
Save the Remmina Main Window size to assure the main geometry at each restart.
void remmina_main_on_action_application_mpchange(GSimpleAction *action, GVariant *param, gpointer data)
static GActionEntry app_actions[]
void remmina_main_on_view_toggle()
gboolean(* is_service_available)(struct _RemminaSecretPlugin *instance)
void remmina_icon_populate_menu(void)
void remmina_main_on_action_connection_delete_multiple(GSimpleAction *action, GVariant *param, gpointer data)
gchar * remmina_file_get_datetime(RemminaFile *remminafile)
Return the string date of the last time a Remmina state file has been modified.
static void remmina_main_file_model_on_sort(GtkTreeSortable *sortable, gpointer user_data)
GtkWidget * remmina_main_new(void)
void remmina_main_on_action_help_debug(GSimpleAction *action, GVariant *param, gpointer data)
gint remmina_string_array_find(RemminaStringArray *array, const gchar *str)
gchar * remmina_string_array_to_string(RemminaStringArray *array)
GtkSwitch * switch_dark_mode
void remmina_main_on_destroy_event()
Called when the remminamain->window widget is destroyed (glade event handler)
void remmina_file_generate_filename(RemminaFile *remminafile)
Generate a new Remmina connection profile file name.
void remmina_main_save_before_destroy()
Save the Remmina Main Window size and the expanded group before to close Remmina. ...
const gchar * description
void remmina_main_on_accel_application_preferences(GSimpleAction *action, GVariant *param, gpointer data)
static void remmina_main_load_file_list_callback(RemminaFile *remminafile, gpointer user_data)
static gboolean remmina_main_load_file_tree_traverse(GNode *node, GtkTreeStore *store, GtkTreeIter *parent)
GtkTreeModel * file_model_filter
static gboolean remmina_main_load_file_tree_find(GtkTreeModel *tree, GtkTreeIter *iter, const gchar *match_group)
void remmina_main_on_action_help_wiki(GSimpleAction *action, GVariant *param, gpointer data)
void remmina_main_on_action_application_default(GSimpleAction *action, GVariant *param, gpointer data)
void remmina_main_load_files_cb(GtkEntry *entry, char *string, gpointer user_data)
gboolean remmina_main_on_window_state_event(GtkWidget *widget, GdkEventWindowState *event, gpointer user_data)
void remmina_main_update_file_datetime(RemminaFile *file)
GtkMenuButton * menu_header_button
static void remmina_main_load_file_tree_group(GtkTreeStore *store)
void remmina_main_on_action_connection_copy(GSimpleAction *action, GVariant *param, gpointer data)
void remmina_plugin_manager_show(GtkWindow *parent)
static void remmina_main_import_file_list(GSList *files)
void remmina_main_on_action_collapse(GSimpleAction *action, GVariant *param, gpointer data)
gboolean remmina_main_idle_destroy(gpointer data)
static gboolean remmina_main_tree_row_activated(GtkTreeView *tree, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data)
void remmina_main_on_action_help_donations(GSimpleAction *action, GVariant *param, gpointer data)
void remmina_main_show_dialog(GtkMessageType msg, GtkButtonsType buttons, const gchar *message)
GtkComboBoxText * combo_quick_connect_protocol
gboolean prevent_snap_welcome_message
GtkBox * box_quick_connect
void remmina_main_on_drag_data_received(GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y, GtkSelectionData *data, guint info, guint time, gpointer user_data)
GtkTreeViewColumn * column_files_list_server
void remmina_main_show_warning_dialog(const gchar *message)
void remmina_main_on_action_connection_new(GSimpleAction *action, GVariant *param, gpointer data)
void remmina_main_quick_search_enter(GtkWidget *widget, gpointer user_data)
void remmina_file_delete(const gchar *filename)
GtkMenu * menu_popup_full
void remmina_string_array_free(RemminaStringArray *array)
GtkStatusbar * statusbar_main
GtkTreeViewColumn * column_files_list_plugin
void remmina_main_quick_search_on_changed(GtkEditable *editable, gpointer user_data)
void remmina_main_on_action_application_preferences(GSimpleAction *action, GVariant *param, gpointer data)
GtkBuilder * remmina_public_gtk_builder_new_from_resource(gchar *resource)
void remmina_main_on_action_connection_delete(GSimpleAction *action, GVariant *param, gpointer data)
static gboolean is_empty(const gchar *s)
RemminaStringArray * remmina_string_array_new_from_string(const gchar *strs)
gboolean remmina_pref_get_boolean(const gchar *key)
RemminaStringArray * remmina_string_array_new(void)
void remmina_file_touch(RemminaFile *remminafile)
Update the atime and mtime of a given filename.
GtkWidget * remmina_file_editor_new_from_filename(const gchar *filename)
static void remmina_main_save_expanded_group_func(GtkTreeView *tree_view, GtkTreePath *path, gpointer user_data)
void remmina_main_on_show(GtkWidget *w, gpointer user_data)
static void remmina_main_init(void)
GtkTreeView * tree_files_list
static void remmina_main_select_file(const gchar *filename)
gboolean remmina_main_on_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
void remmina_main_on_action_help_community(GSimpleAction *action, GVariant *param, gpointer data)
GtkToggleButton * view_toggle_button
void remmina_main_destroy()
RemminaFile * remmina_file_new(void)
GtkTreeViewColumn * column_files_list_group
void remmina_main_file_list_on_row_activated(GtkTreeView *tree, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data)
static void remmina_main_expand_group_traverse(GtkTreeIter *iter)
RemminaStringArray * expanded_group
static gboolean remmina_main_selection_func(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer user_data)
void remmina_main_on_action_connection_external_tools(GSimpleAction *action, GVariant *param, gpointer data)
static void remmina_main_clear_selection_data(void)
void rcw_open_from_file(RemminaFile *remminafile)
void remmina_main_on_date_column_sort_clicked()
gboolean remmina_main_file_list_on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
gint remmina_file_get_int(RemminaFile *remminafile, const gchar *setting, gint default_value)
void remmina_main_on_action_application_dark_theme(GSimpleAction *action, GVariant *param, gpointer data)
void remmina_about_open(GtkWindow *parent)
GtkWidget * remmina_file_editor_new(void)
RemminaPlugin * remmina_plugin_manager_get_plugin(RemminaPluginType type, const gchar *name)
static gboolean remmina_main_add_tool_plugin(gchar *name, RemminaPlugin *plugin, gpointer user_data)
gboolean remmina_pref_save(void)
void remmina_main_on_action_connection_edit(GSimpleAction *action, GVariant *param, gpointer data)
void remmina_main_toggle_password_view(GtkWidget *widget, gpointer data)
GtkTreeModel * file_model_sort
gboolean rcw_open_from_filename(const gchar *filename)
static const gchar * supported_mime_types[]
void remmina_main_on_action_expand(GSimpleAction *action, GVariant *param, gpointer data)
gboolean(* export_func)(struct _RemminaFilePlugin *instance, RemminaFile *file, const gchar *to_file)
void remmina_application_condexit(RemminaCondExitType why)
void remmina_file_set_string(RemminaFile *remminafile, const gchar *setting, const gchar *value)
static char * quick_connect_plugin_list[]
void remmina_file_save(RemminaFile *remminafile)
GtkTreeViewColumn * column_files_list_notes
static gboolean remmina_main_quickconnect(void)
gboolean always_show_notes
void remmina_string_array_add(RemminaStringArray *array, const gchar *str)
static GtkTargetEntry remmina_drop_types[]
GtkSearchBar * search_bar
static RemminaMain * remminamain
GtkWidget * remmina_file_editor_new_copy(const gchar *filename)
void remmina_main_on_action_application_quit(GSimpleAction *action, GVariant *param, gpointer data)
GtkEntry * entry_quick_connect_server
gint remmina_unlock_new(GtkWindow *parent)
const gchar * remmina_file_get_icon_name(RemminaFile *remminafile)
void remmina_mpchange_schedule(gboolean has_domain, const gchar *group, const gchar *domain, const gchar *username, const gchar *password, const gchar *gatewayusername, const gchar *gatewaydomain, const gchar *gatewaypassword)
GtkWidget * remmina_pref_dialog_new(gint default_tab, GtkWindow *parent)
GNode * remmina_file_manager_get_group_tree(void)
void remmina_main_on_action_search_toggle(GSimpleAction *action, GVariant *param, gpointer data)
gboolean override_view_file_mode_to_list
void remmina_main_on_action_tools_export(GSimpleAction *action, GVariant *param, gpointer data)
static void remmina_main_file_editor_destroy(GtkWidget *widget, gpointer user_data)
gint remmina_file_manager_iterate(GFunc func, gpointer user_data)
static void remmina_main_expand_group(void)
void remmina_main_quick_search_on_icon_press(GtkEntry *entry, GtkEntryIconPosition icon_pos, GdkEvent *event, gpointer user_data)
void remmina_main_on_accel_search_toggle(RemminaMain *remminamain)
static void remmina_main_load_files()
GtkTreeViewColumn * column_files_list_date
void remmina_main_on_action_application_about(GSimpleAction *action, GVariant *param, gpointer data)
static void remmina_main_action_tools_import_on_response(GtkDialog *dialog, gint response_id, gpointer user_data)
void remmina_main_on_action_application_plugins(GSimpleAction *action, GVariant *param, gpointer data)
static gboolean remmina_main_dexit(gpointer data)
Try to exit remmina after a delete window event.
gboolean remmina_main_quickconnect_on_click(GtkWidget *widget, gpointer user_data)