From 5b52622db7ee7d9021b1a5e5a1be52242ff2b719 Mon Sep 17 00:00:00 2001 From: Antenore Gatta Date: Fri, 16 Jun 2023 13:02:20 +0000 Subject: Automatic doc build by remmina-ci --- public/globals_func_r.html | 407 ++++++++++++----------- public/globals_r.html | 367 ++++++++++---------- public/navtreedata.js | 24 +- public/navtreeindex10.js | 4 +- public/navtreeindex11.js | 4 +- public/navtreeindex12.js | 4 +- public/navtreeindex13.js | 4 +- public/navtreeindex14.js | 4 +- public/navtreeindex15.js | 4 +- public/navtreeindex16.js | 4 +- public/navtreeindex17.js | 4 +- public/navtreeindex18.js | 1 + public/navtreeindex5.js | 6 +- public/navtreeindex6.js | 14 +- public/navtreeindex7.js | 10 +- public/navtreeindex8.js | 4 +- public/navtreeindex9.js | 4 +- public/rcw_8c_source.html | 8 +- public/remmina__exec_8c_source.html | 8 +- public/remmina__file_8c_source.html | 4 +- public/remmina__file__editor_8c.html | 122 +++---- public/remmina__file__editor_8c.js | 1 - public/remmina__file__editor_8c_source.html | 89 +++-- public/remmina__file__editor_8h.html | 14 +- public/remmina__file__editor_8h_source.html | 14 +- public/remmina__main_8c.html | 128 ++++--- public/remmina__main_8c.js | 1 + public/remmina__main_8c_source.html | 79 ++--- public/remmina__main_8h.html | 68 +++- public/remmina__main_8h.js | 1 + public/remmina__main_8h_source.html | 37 ++- public/remmina__message__panel_8c.html | 40 +-- public/remmina__message__panel_8c_source.html | 50 +-- public/remmina__message__panel_8h.html | 28 +- public/remmina__message__panel_8h_source.html | 28 +- public/remmina__mpchange_8c_source.html | 2 +- public/remmina__plugin__manager_8c_source.html | 4 +- public/remmina__protocol__widget_8c_source.html | 24 +- public/search/all_12.js | 2 +- public/search/functions_11.js | 2 +- public/struct_remmina_message_panel_private.html | 8 +- 41 files changed, 831 insertions(+), 800 deletions(-) diff --git a/public/globals_func_r.html b/public/globals_func_r.html index 65edc4d17..acd5c3598 100644 --- a/public/globals_func_r.html +++ b/public/globals_func_r.html @@ -1008,9 +1008,6 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : remmina_file.c , remmina_file.h -
  • remmina_file_toggle_password_view() -: remmina_file_editor.c -
  • remmina_file_touch() : remmina_file.c , remmina_file.h @@ -1397,8 +1394,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_main.h
  • remmina_main_on_action_application_default() -: remmina_main.c -, remmina_main.h +: remmina_main.h +, remmina_main.c
  • remmina_main_on_action_application_mpchange() : remmina_main.c @@ -1558,6 +1555,10 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : remmina_main.c , remmina_main.h
  • +
  • remmina_main_toggle_password_view() +: remmina_main.c +, remmina_main.h +
  • remmina_main_tree_row_activated() : remmina_main.c
  • @@ -2199,8 +2200,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : vnc_plugin.c
  • remmina_plugin_vnc_update_scale() -: vnc_plugin.c -, vnc_plugin.h +: vnc_plugin.h +, vnc_plugin.c
  • remmina_plugin_www_close_connection() : www_plugin.c @@ -2210,15 +2211,15 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , www_plugin.h
  • remmina_plugin_www_decide_newwin() -: www_plugin.h -, www_plugin.c +: www_plugin.c +, www_plugin.h
  • remmina_plugin_www_decide_policy_cb() : www_plugin.c
  • remmina_plugin_www_decide_resource() -: www_plugin.c -, www_plugin.h +: www_plugin.h +, www_plugin.c
  • remmina_plugin_www_download_started() : www_plugin.c @@ -2249,8 +2250,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : www_plugin.c
  • remmina_plugin_www_response_received() -: www_plugin.c -, www_plugin.h +: www_plugin.h +, www_plugin.c
  • remmina_plugin_www_save_snapshot() : www_plugin.c @@ -2260,8 +2261,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_pref.h
  • remmina_pref_clear_recent() -: remmina_pref.h -, remmina_pref.c +: remmina_pref.c +, remmina_pref.h
  • remmina_pref_dialog_add_pref_plugin() : remmina_pref_dialog.c @@ -2280,8 +2281,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : remmina_pref_dialog.c
  • remmina_pref_dialog_new() -: remmina_pref_dialog.h -, remmina_pref_dialog.c +: remmina_pref_dialog.c +, remmina_pref_dialog.h
  • remmina_pref_dialog_on_action_close() : remmina_pref_dialog.c @@ -2317,8 +2318,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : remmina_pref.c
  • remmina_pref_get_recent() -: remmina_pref.c -, remmina_pref.h +: remmina_pref.h +, remmina_pref.c
  • remmina_pref_get_scale_quality() : remmina_pref.c @@ -2328,15 +2329,15 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : python_wrapper_remmina.c
  • remmina_pref_get_ssh_loglevel() -: remmina_pref.h -, remmina_pref.c +: remmina_pref.c +, remmina_pref.h
  • remmina_pref_get_ssh_loglevel_wrapper() : python_wrapper_remmina.c
  • remmina_pref_get_ssh_parseconfig() -: remmina_pref.c -, remmina_pref.h +: remmina_pref.h +, remmina_pref.c
  • remmina_pref_get_ssh_parseconfig_wrapper() : python_wrapper_remmina.c @@ -2354,8 +2355,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_pref.h
  • remmina_pref_get_ssh_tcp_usrtimeout() -: remmina_pref.h -, remmina_pref.c +: remmina_pref.c +, remmina_pref.h
  • remmina_pref_get_sshtunnel_port() : remmina_pref.c @@ -2372,8 +2373,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : python_wrapper_remmina.c
  • remmina_pref_init() -: remmina_pref.h -, remmina_pref.c +: remmina_pref.c +, remmina_pref.h
  • remmina_pref_init_keymap() : remmina_pref.c @@ -2390,8 +2391,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : python_wrapper_remmina.c
  • remmina_pref_keymap_get_table() -: remmina_pref.h -, remmina_pref.c +: remmina_pref.c +, remmina_pref.h
  • remmina_pref_keymap_groups() : remmina_pref.c @@ -2410,8 +2411,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : remmina_pref_dialog.c
  • remmina_pref_save() -: remmina_pref.h -, remmina_pref.c +: remmina_pref.c +, remmina_pref.h
  • remmina_pref_set_value() : remmina_pref.c @@ -2473,8 +2474,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_call_feature_by_type() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_chat_close() : remmina_protocol_widget.c @@ -2484,8 +2485,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : remmina_protocol_widget.c
  • remmina_protocol_widget_chat_open() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_chat_receive() : remmina_protocol_widget.c @@ -2519,16 +2520,16 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_get_cacert() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_get_cacrl() : remmina_protocol_widget.c , remmina_protocol_widget.h
  • remmina_protocol_widget_get_clientcert() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_get_clientkey() : remmina_protocol_widget.c @@ -2543,24 +2544,24 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_get_error_message() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_get_expand() : remmina_protocol_widget.c , remmina_protocol_widget.h
  • remmina_protocol_widget_get_features() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_get_file() : remmina_protocol_widget.c , remmina_protocol_widget.h
  • remmina_protocol_widget_get_gtkwindow() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_get_height() : remmina_protocol_widget.c @@ -2575,8 +2576,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_get_password() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_get_profile_remote_height() : remmina_protocol_widget.c @@ -2586,15 +2587,15 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : python_wrapper_remmina.c
  • remmina_protocol_widget_get_profile_remote_width() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_get_profile_remote_width_wrapper() : python_wrapper_remmina.c
  • remmina_protocol_widget_get_savepassword() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_get_type() : remmina_protocol_widget.h @@ -2612,8 +2613,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_gtkviewport() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_has_error() : remmina_protocol_widget.c @@ -2646,8 +2647,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_new() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_on_key_press() : remmina_protocol_widget.c @@ -2656,8 +2657,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : remmina_protocol_widget.c
  • remmina_protocol_widget_open_connection() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_open_connection_real() : remmina_protocol_widget.c @@ -2667,8 +2668,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_panel_authuserpwd_ssh_tunnel() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_panel_authx509() : remmina_protocol_widget.c @@ -2682,24 +2683,24 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : remmina_protocol_widget.h
  • remmina_protocol_widget_panel_hide() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_panel_new_certificate() : remmina_protocol_widget.c , remmina_protocol_widget.h
  • remmina_protocol_widget_panel_question_yesno() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_panel_show() : remmina_protocol_widget.c , remmina_protocol_widget.h
  • remmina_protocol_widget_panel_show_listen() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_panel_show_retry() : remmina_protocol_widget.c @@ -2714,16 +2715,16 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_query_feature_by_ref() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_query_feature_by_type() : remmina_protocol_widget.c , remmina_protocol_widget.h
  • remmina_protocol_widget_register_hostkey() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_save_cred() : remmina_protocol_widget.c @@ -2733,8 +2734,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : remmina_protocol_widget.c
  • remmina_protocol_widget_send_clipboard() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_send_keys_signals() : remmina_protocol_widget.c @@ -2749,24 +2750,24 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_set_display() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_set_error() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_set_expand() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_set_height() : remmina_protocol_widget.c , remmina_protocol_widget.h
  • remmina_protocol_widget_set_hostkey_func() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_set_width() : remmina_protocol_widget.c @@ -2781,24 +2782,24 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_signal_connection_opened() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_ssh_exec() : remmina_protocol_widget.c , remmina_protocol_widget.h
  • remmina_protocol_widget_start_direct_tunnel() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_start_reverse_tunnel() : remmina_protocol_widget.c , remmina_protocol_widget.h
  • remmina_protocol_widget_start_xport_tunnel() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_tunnel_destroy() : remmina_protocol_widget.c @@ -2883,24 +2884,24 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : python_wrapper_remmina.c
  • remmina_public_get_xauth_cookie() -: remmina_public.h -, remmina_public.c +: remmina_public.c +, remmina_public.h
  • remmina_public_gtk_builder_new_from_file() -: remmina_public.h -, remmina_public.c +: remmina_public.c +, remmina_public.h
  • remmina_public_gtk_builder_new_from_resource() -: remmina_public.h -, remmina_public.c +: remmina_public.c +, remmina_public.h
  • remmina_public_gtk_widget_reparent() : remmina_public.h , remmina_public.c
  • remmina_public_load_combo_text_d() -: remmina_public.h -, remmina_public.c +: remmina_public.c +, remmina_public.h
  • remmina_public_open_unix_sock() : remmina_public.c @@ -2915,24 +2916,24 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_public.h
  • remmina_public_resolution_validation_func() -: remmina_public.h -, remmina_public.c +: remmina_public.c +, remmina_public.h
  • remmina_public_send_notification() -: remmina_public.h -, remmina_public.c +: remmina_public.c +, remmina_public.h
  • remmina_public_split_resolution_string() -: remmina_public.h -, remmina_public.c +: remmina_public.c +, remmina_public.h
  • remmina_public_str_replace() : remmina_public.h , remmina_public.c
  • remmina_public_str_replace_in_place() -: remmina_public.h -, remmina_public.c +: remmina_public.c +, remmina_public.h
  • remmina_rdp_authenticate() : rdp_plugin.c @@ -2948,26 +2949,26 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , rdp_cliprdr.h
  • remmina_rdp_clipboard_free() -: rdp_cliprdr.c -, rdp_cliprdr.h +: rdp_cliprdr.h +, rdp_cliprdr.c
  • remmina_rdp_clipboard_init() -: rdp_cliprdr.c -, rdp_cliprdr.h +: rdp_cliprdr.h +, rdp_cliprdr.c
  • remmina_rdp_cliprdr_cached_clipboard_free() : rdp_cliprdr.c
  • remmina_rdp_cliprdr_detach_owner() -: rdp_cliprdr.h -, rdp_cliprdr.c +: rdp_cliprdr.c +, rdp_cliprdr.h
  • remmina_rdp_cliprdr_empty_clipboard() : rdp_cliprdr.c
  • remmina_rdp_cliprdr_get_client_format_list() -: rdp_cliprdr.c -, rdp_cliprdr.h +: rdp_cliprdr.h +, rdp_cliprdr.c
  • remmina_rdp_cliprdr_get_clipboard_data() : rdp_cliprdr.c @@ -2979,8 +2980,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : rdp_cliprdr.c
  • remmina_rdp_cliprdr_init() -: rdp_cliprdr.h -, rdp_cliprdr.c +: rdp_cliprdr.c +, rdp_cliprdr.h
  • remmina_rdp_cliprdr_monitor_ready() : rdp_cliprdr.c @@ -3046,8 +3047,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : rdp_event.c
  • remmina_rdp_event_event_push() -: rdp_event.c -, rdp_plugin.h +: rdp_plugin.h +, rdp_event.c
  • remmina_rdp_event_free_cursor() : rdp_event.c @@ -3056,8 +3057,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : rdp_event.c
  • remmina_rdp_event_init() -: rdp_event.c -, rdp_event.h +: rdp_event.h +, rdp_event.c
  • remmina_rdp_event_init_keymap() : rdp_event.c @@ -3081,8 +3082,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : rdp_event.c
  • remmina_rdp_event_on_map() -: rdp_event.h -, rdp_event.c +: rdp_event.c +, rdp_event.h
  • remmina_rdp_event_on_motion() : rdp_event.c @@ -3091,8 +3092,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : rdp_event.c
  • remmina_rdp_event_on_unmap() -: rdp_event.h -, rdp_event.c +: rdp_event.c +, rdp_event.h
  • remmina_rdp_event_process_clipboard() : rdp_cliprdr.h @@ -3111,16 +3112,16 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : rdp_event.c
  • remmina_rdp_event_queue_ui_async() -: rdp_event.h -, rdp_event.c +: rdp_event.c +, rdp_event.h
  • remmina_rdp_event_queue_ui_sync_retint() : rdp_event.h , rdp_event.c
  • remmina_rdp_event_queue_ui_sync_retptr() -: rdp_event.h -, rdp_event.c +: rdp_event.c +, rdp_event.h
  • remmina_rdp_event_reconnect_progress() : rdp_event.c @@ -3138,8 +3139,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : rdp_event.c
  • remmina_rdp_event_send_delayed_monitor_layout() -: rdp_event.c -, rdp_event.h +: rdp_event.h +, rdp_event.c
  • remmina_rdp_event_set_pointer_position() : rdp_event.c @@ -3148,23 +3149,23 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : rdp_event.c
  • remmina_rdp_event_unfocus() -: rdp_event.c -, rdp_event.h +: rdp_event.h +, rdp_event.c
  • remmina_rdp_event_uninit() -: rdp_event.c -, rdp_event.h +: rdp_event.h +, rdp_event.c
  • remmina_rdp_event_update_rect() -: rdp_event.c -, rdp_event.h +: rdp_event.h +, rdp_event.c
  • remmina_rdp_event_update_regions() : rdp_event.c
  • remmina_rdp_event_update_scale() -: rdp_event.h -, rdp_event.c +: rdp_event.c +, rdp_event.h
  • remmina_rdp_event_update_scale_factor() : rdp_event.c @@ -3177,12 +3178,12 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : rdp_file.c
  • remmina_rdp_file_export_test() -: rdp_file.h -, rdp_file.c +: rdp_file.c +, rdp_file.h
  • remmina_rdp_file_import() -: rdp_file.h -, rdp_file.c +: rdp_file.c +, rdp_file.h
  • remmina_rdp_file_import_channel() : rdp_file.c @@ -3226,8 +3227,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , rdp_monitor.h
  • remmina_rdp_OnChannelConnectedEventHandler() -: rdp_channels.c -, rdp_channels.h +: rdp_channels.h +, rdp_channels.c
  • remmina_rdp_OnChannelDisconnectedEventHandler() : rdp_channels.c @@ -3261,8 +3262,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : rdp_settings.c
  • remmina_rdp_settings_get_keyboard_layout() -: rdp_settings.h -, rdp_settings.c +: rdp_settings.c +, rdp_settings.h
  • remmina_rdp_settings_get_orientation_scale_prefs() : rdp_settings.c @@ -3340,8 +3341,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : remmina_scheduler.c
  • remmina_scheduler_setup() -: remmina_scheduler.c -, remmina_scheduler.h +: remmina_scheduler.h +, remmina_scheduler.c
  • remmina_scrolled_viewport_class_init() : remmina_scrolled_viewport.c @@ -3391,8 +3392,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : remmina_ssh_plugin.c
  • remmina_sftp_client_confirm_resume() -: remmina_sftp_client.h -, remmina_sftp_client.c +: remmina_sftp_client.c +, remmina_sftp_client.h
  • remmina_sftp_client_destroy() : remmina_sftp_client.c @@ -3420,8 +3421,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : remmina_sftp_client.c
  • remmina_sftp_client_open() -: remmina_sftp_client.c -, remmina_sftp_client.h +: remmina_sftp_client.h +, remmina_sftp_client.c
  • remmina_sftp_client_refresh() : remmina_sftp_client.c @@ -3483,24 +3484,24 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_utils.c
  • remmina_sodium_init() -: remmina_sodium.c -, remmina_sodium.h +: remmina_sodium.h +, remmina_sodium.c
  • remmina_sodium_pwhash() -: remmina_sodium.c -, remmina_sodium.h +: remmina_sodium.h +, remmina_sodium.c
  • remmina_sodium_pwhash_str() -: remmina_sodium.h -, remmina_sodium.c +: remmina_sodium.c +, remmina_sodium.h
  • remmina_sodium_pwhash_str_verify() -: remmina_sodium.c -, remmina_sodium.h +: remmina_sodium.h +, remmina_sodium.c
  • remmina_ssh_auth() -: remmina_ssh.h -, remmina_ssh.c +: remmina_ssh.c +, remmina_ssh.h
  • remmina_ssh_auth_agent() : remmina_ssh.c @@ -3578,19 +3579,19 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_ssh_plugin.h
  • remmina_ssh_plugin_register() -: remmina_ssh_plugin.h -, remmina_ssh_plugin.c +: remmina_ssh_plugin.c +, remmina_ssh_plugin.h
  • remmina_ssh_search_item() : remmina_ssh.c
  • remmina_ssh_set_application_error() -: remmina_ssh.c -, remmina_ssh.h +: remmina_ssh.h +, remmina_ssh.c
  • remmina_ssh_set_error() -: remmina_ssh.h -, remmina_ssh.c +: remmina_ssh.c +, remmina_ssh.h
  • remmina_ssh_set_nodelay() : remmina_ssh.c @@ -3647,8 +3648,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : remmina_ssh.c
  • remmina_stats_get_all() -: remmina_stats.h -, remmina_stats.c +: remmina_stats.c +, remmina_stats.h
  • remmina_stats_get_gtk_backend() : remmina_stats.c @@ -3699,12 +3700,12 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_string_array.h
  • remmina_string_array_intersect() -: remmina_string_array.c -, remmina_string_array.h +: remmina_string_array.h +, remmina_string_array.c
  • remmina_string_array_new() -: remmina_string_array.c -, remmina_string_array.h +: remmina_string_array.h +, remmina_string_array.c
  • remmina_string_array_new_from_allocated_string() : remmina_string_array.h @@ -3715,24 +3716,24 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_string_array.h
  • remmina_string_array_remove() -: remmina_string_array.c -, remmina_string_array.h +: remmina_string_array.h +, remmina_string_array.c
  • remmina_string_array_remove_index() -: remmina_string_array.c -, remmina_string_array.h +: remmina_string_array.h +, remmina_string_array.c
  • remmina_string_array_sort() : remmina_string_array.h , remmina_string_array.c
  • remmina_string_array_to_string() -: remmina_string_array.h -, remmina_string_array.c +: remmina_string_array.c +, remmina_string_array.h
  • remmina_string_list_get_text() -: remmina_string_list.h -, remmina_string_list.c +: remmina_string_list.c +, remmina_string_list.h
  • remmina_string_list_init() : remmina_string_list.c @@ -3760,8 +3761,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : remmina_string_list.c
  • remmina_string_list_set_text() -: remmina_string_list.h -, remmina_string_list.c +: remmina_string_list.c +, remmina_string_list.h
  • remmina_string_list_set_titles() : remmina_string_list.c @@ -3775,16 +3776,16 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : remmina_string_list.c
  • remmina_sysinfo_get_gnome_shell_version() -: remmina_sysinfo.h -, remmina_sysinfo.c +: remmina_sysinfo.c +, remmina_sysinfo.h
  • remmina_sysinfo_get_wm_name() : remmina_sysinfo.c , remmina_sysinfo.h
  • remmina_sysinfo_is_appindicator_available() -: remmina_sysinfo.c -, remmina_sysinfo.h +: remmina_sysinfo.h +, remmina_sysinfo.c
  • remmina_tp_channel_handler_accept() : telepathy_channel_handler.c @@ -3862,8 +3863,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : remmina_unlock.c
  • remmina_utils_get_etc_release() -: remmina_utils.h -, remmina_utils.c +: remmina_utils.c +, remmina_utils.h
  • remmina_utils_get_kernel_arch() : remmina_utils.h @@ -3878,24 +3879,24 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_utils.h
  • remmina_utils_get_lang() -: remmina_utils.h -, remmina_utils.c +: remmina_utils.c +, remmina_utils.h
  • remmina_utils_get_lsb_codename() -: remmina_utils.c -, remmina_utils.h +: remmina_utils.h +, remmina_utils.c
  • remmina_utils_get_lsb_description() -: remmina_utils.h -, remmina_utils.c +: remmina_utils.c +, remmina_utils.h
  • remmina_utils_get_lsb_id() -: remmina_utils.c -, remmina_utils.h +: remmina_utils.h +, remmina_utils.c
  • remmina_utils_get_lsb_release() -: remmina_utils.c -, remmina_utils.h +: remmina_utils.h +, remmina_utils.c
  • remmina_utils_get_os_info() : remmina_utils.c @@ -3909,16 +3910,16 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); , remmina_utils.c
  • remmina_utils_string_replace() -: remmina_utils.h -, remmina_utils.c +: remmina_utils.c +, remmina_utils.h
  • remmina_utils_string_replace_all() : remmina_utils.c , remmina_utils.h
  • remmina_utils_string_strip() -: remmina_utils.h -, remmina_utils.c +: remmina_utils.c +, remmina_utils.h
  • remmina_utils_strpos() : remmina_utils.c @@ -3947,8 +3948,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : remmina_widget_pool.c
  • remmina_widget_pool_register() -: remmina_widget_pool.h -, remmina_widget_pool.c +: remmina_widget_pool.c +, remmina_widget_pool.h
  • remmina_widget_pool_register_wrapper() : python_wrapper_remmina.c @@ -4044,8 +4045,8 @@ $(document).ready(function(){initNavTree('globals_func_r.html','');}); : rdp_plugin.c
  • rf_register_graphics() -: rdp_graphics.h -, rdp_graphics.c +: rdp_graphics.c +, rdp_graphics.h
  • rf_uninit() : rdp_plugin.h diff --git a/public/globals_r.html b/public/globals_r.html index d1e759761..904d17ff8 100644 --- a/public/globals_r.html +++ b/public/globals_r.html @@ -1122,9 +1122,6 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_file.c , remmina_file.h
  • -
  • remmina_file_toggle_password_view() -: remmina_file_editor.c -
  • remmina_file_touch() : remmina_file.c , remmina_file.h @@ -1429,8 +1426,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_icon.h
  • remmina_icon_is_autostart() -: remmina_icon.c -, remmina_icon.h +: remmina_icon.h +, remmina_icon.c
  • remmina_icon_is_available() : remmina_icon.c @@ -1783,6 +1780,10 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_main.c , remmina_main.h
  • +
  • remmina_main_toggle_password_view() +: remmina_main.c +, remmina_main.h +
  • remmina_main_tree_row_activated() : remmina_main.c
  • @@ -2757,8 +2758,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_pref.c
  • remmina_pref_file_load_colors() -: remmina_pref.c -, remmina_pref.h +: remmina_pref.h +, remmina_pref.c
  • remmina_pref_gen_secret() : remmina_pref.c @@ -2771,8 +2772,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_pref.c
  • remmina_pref_get_recent() -: remmina_pref.h -, remmina_pref.c +: remmina_pref.c +, remmina_pref.h
  • remmina_pref_get_scale_quality() : remmina_pref.c @@ -2796,24 +2797,24 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : python_wrapper_remmina.c
  • remmina_pref_get_ssh_tcp_keepcnt() -: remmina_pref.c -, remmina_pref.h +: remmina_pref.h +, remmina_pref.c
  • remmina_pref_get_ssh_tcp_keepidle() : remmina_pref.c , remmina_pref.h
  • remmina_pref_get_ssh_tcp_keepintvl() -: remmina_pref.c -, remmina_pref.h +: remmina_pref.h +, remmina_pref.c
  • remmina_pref_get_ssh_tcp_usrtimeout() : remmina_pref.c , remmina_pref.h
  • remmina_pref_get_sshtunnel_port() -: remmina_pref.c -, remmina_pref.h +: remmina_pref.h +, remmina_pref.c
  • remmina_pref_get_sshtunnel_port_wrapper() : python_wrapper_remmina.c @@ -2833,8 +2834,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_pref.c
  • remmina_pref_is_rw() -: remmina_pref.h -, remmina_pref.c +: remmina_pref.c +, remmina_pref.h
  • remmina_pref_keymap_get_keyval() : remmina_pref.c @@ -2848,8 +2849,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_pref.h
  • remmina_pref_keymap_groups() -: remmina_pref.c -, remmina_pref.h +: remmina_pref.h +, remmina_pref.c
  • remmina_pref_on_button_keystrokes_clicked() : remmina_pref_dialog.c @@ -2871,8 +2872,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_pref.h
  • remmina_pref_set_value() -: remmina_pref.h -, remmina_pref.c +: remmina_pref.c +, remmina_pref.h
  • remmina_pref_set_value_wrapper() : python_wrapper_remmina.c @@ -3011,8 +3012,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_call_feature_by_type() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_chat_close() : remmina_protocol_widget.c @@ -3026,8 +3027,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_chat_receive() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_class_init() : remmina_protocol_widget.c @@ -3057,16 +3058,16 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_get_cacert() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_get_cacrl() : remmina_protocol_widget.c , remmina_protocol_widget.h
  • remmina_protocol_widget_get_clientcert() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_get_clientkey() : remmina_protocol_widget.c @@ -3081,24 +3082,24 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_get_error_message() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_get_expand() : remmina_protocol_widget.c , remmina_protocol_widget.h
  • remmina_protocol_widget_get_features() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_get_file() : remmina_protocol_widget.c , remmina_protocol_widget.h
  • remmina_protocol_widget_get_gtkwindow() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_get_height() : remmina_protocol_widget.c @@ -3113,8 +3114,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_get_password() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_get_profile_remote_height() : remmina_protocol_widget.c @@ -3131,8 +3132,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : python_wrapper_remmina.c
  • remmina_protocol_widget_get_savepassword() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_get_type() : remmina_protocol_widget.h @@ -3146,16 +3147,16 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_grab_focus() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_gtkviewport() : remmina_protocol_widget.c , remmina_protocol_widget.h
  • remmina_protocol_widget_has_error() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_init() : remmina_protocol_widget.c @@ -3164,8 +3165,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_protocol_widget.c
  • remmina_protocol_widget_is_closed() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_lock_dynres() : remmina_protocol_widget.c @@ -3180,8 +3181,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_mpprogress() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_new() : remmina_protocol_widget.c @@ -3201,8 +3202,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_protocol_widget.c
  • remmina_protocol_widget_panel_auth() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_panel_authuserpwd_ssh_tunnel() : remmina_protocol_widget.c @@ -3224,16 +3225,16 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_panel_new_certificate() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_panel_question_yesno() : remmina_protocol_widget.c , remmina_protocol_widget.h
  • remmina_protocol_widget_panel_show() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_panel_show_listen() : remmina_protocol_widget.c @@ -3248,24 +3249,24 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_plugin_screenshot() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_query_feature_by_ref() : remmina_protocol_widget.c , remmina_protocol_widget.h
  • remmina_protocol_widget_query_feature_by_type() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_register_hostkey() : remmina_protocol_widget.c , remmina_protocol_widget.h
  • remmina_protocol_widget_save_cred() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • REMMINA_PROTOCOL_WIDGET_SCALE_MODE_DYNRES : types.h @@ -3284,24 +3285,24 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_send_keys_signals() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_send_keystrokes() : remmina_protocol_widget.c , remmina_protocol_widget.h
  • remmina_protocol_widget_set_current_scale_mode() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_set_display() : remmina_protocol_widget.c , remmina_protocol_widget.h
  • remmina_protocol_widget_set_error() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_set_expand() : remmina_protocol_widget.c @@ -3324,8 +3325,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_signal_connection_closed() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_signal_connection_opened() : remmina_protocol_widget.c @@ -3335,8 +3336,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_protocol_widget.c
  • remmina_protocol_widget_ssh_exec() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_start_direct_tunnel() : remmina_protocol_widget.c @@ -3358,8 +3359,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_protocol_widget.h
  • remmina_protocol_widget_unmap_event() -: remmina_protocol_widget.c -, remmina_protocol_widget.h +: remmina_protocol_widget.h +, remmina_protocol_widget.c
  • remmina_protocol_widget_update_align() : remmina_protocol_widget.c @@ -3369,8 +3370,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : rcw.c
  • remmina_protocol_widget_update_remote_resolution() -: remmina_protocol_widget.h -, remmina_protocol_widget.c +: remmina_protocol_widget.c +, remmina_protocol_widget.h
  • remmina_protocol_widget_xport_tunnel_connect_callback() : remmina_protocol_widget.c @@ -3386,24 +3387,24 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_public.h
  • remmina_public_combo_get_active_text() -: remmina_public.c -, remmina_public.h +: remmina_public.h +, remmina_public.c
  • remmina_public_create_combo() : remmina_public.c , remmina_public.h
  • remmina_public_create_combo_entry() -: remmina_public.c -, remmina_public.h +: remmina_public.h +, remmina_public.c
  • remmina_public_create_combo_map() : remmina_public.c , remmina_public.h
  • remmina_public_create_combo_mapint() -: remmina_public.c -, remmina_public.h +: remmina_public.h +, remmina_public.c
  • remmina_public_create_combo_text_d() : remmina_public.c @@ -3418,16 +3419,16 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_public.h
  • remmina_public_get_modifier_for_keycode() -: remmina_public.c -, remmina_public.h +: remmina_public.h +, remmina_public.c
  • remmina_public_get_server_port() : remmina_public.c , remmina_public.h
  • remmina_public_get_server_port_old() -: remmina_public.c -, remmina_public.h +: remmina_public.h +, remmina_public.c
  • remmina_public_get_server_port_wrapper() : python_wrapper_remmina.c @@ -3437,8 +3438,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_public.h
  • remmina_public_gtk_builder_new_from_file() -: remmina_public.h -, remmina_public.c +: remmina_public.c +, remmina_public.h
  • remmina_public_gtk_builder_new_from_resource() : remmina_public.c @@ -3453,24 +3454,24 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_public.h
  • remmina_public_open_unix_sock() -: remmina_public.h -, remmina_public.c +: remmina_public.c +, remmina_public.h
  • remmina_public_open_xdisplay() : remmina_public.c , remmina_public.h
  • remmina_public_popup_position() -: remmina_public.h -, remmina_public.c +: remmina_public.c +, remmina_public.h
  • remmina_public_resolution_validation_func() : remmina_public.c , remmina_public.h
  • remmina_public_send_notification() -: remmina_public.h -, remmina_public.c +: remmina_public.c +, remmina_public.h
  • remmina_public_split_resolution_string() : remmina_public.c @@ -3527,8 +3528,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : rdp_cliprdr.c
  • remmina_rdp_cliprdr_detach_owner() -: rdp_cliprdr.h -, rdp_cliprdr.c +: rdp_cliprdr.c +, rdp_cliprdr.h
  • remmina_rdp_cliprdr_empty_clipboard() : rdp_cliprdr.c @@ -3547,8 +3548,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : rdp_cliprdr.c
  • remmina_rdp_cliprdr_init() -: rdp_cliprdr.h -, rdp_cliprdr.c +: rdp_cliprdr.c +, rdp_cliprdr.h
  • remmina_rdp_cliprdr_monitor_ready() : rdp_cliprdr.c @@ -3617,8 +3618,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : rdp_plugin.h
  • remmina_rdp_event_event_push() -: rdp_plugin.h -, rdp_event.c +: rdp_event.c +, rdp_plugin.h
  • remmina_rdp_event_free_cursor() : rdp_event.c @@ -3666,8 +3667,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , rdp_event.c
  • remmina_rdp_event_process_clipboard() -: rdp_cliprdr.h -, rdp_cliprdr.c +: rdp_cliprdr.c +, rdp_cliprdr.h
  • remmina_rdp_event_process_event() : rdp_event.c @@ -3744,12 +3745,12 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , rdp_event.h
  • remmina_rdp_event_uninit() -: rdp_event.c -, rdp_event.h +: rdp_event.h +, rdp_event.c
  • remmina_rdp_event_update_rect() -: rdp_event.h -, rdp_event.c +: rdp_event.c +, rdp_event.h
  • remmina_rdp_event_update_regions() : rdp_event.c @@ -3765,8 +3766,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : rdp_plugin.c
  • remmina_rdp_file_export() -: rdp_file.c -, rdp_file.h +: rdp_file.h +, rdp_file.c
  • remmina_rdp_file_export_channel() : rdp_file.c @@ -3821,8 +3822,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , rdp_monitor.h
  • remmina_rdp_OnChannelConnectedEventHandler() -: rdp_channels.h -, rdp_channels.c +: rdp_channels.c +, rdp_channels.h
  • remmina_rdp_OnChannelDisconnectedEventHandler() : rdp_channels.h @@ -3910,8 +3911,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : rdp_settings.c
  • remmina_rdp_settings_new() -: rdp_settings.c -, rdp_settings.h +: rdp_settings.h +, rdp_settings.c
  • remmina_rdp_settings_quality_on_changed() : rdp_settings.c @@ -3946,18 +3947,18 @@ $(document).ready(function(){initNavTree('globals_r.html','');});
  • REMMINA_RDP_UI_EVENT : rdp_plugin.h
  • -
  • REMMINA_RDP_UI_EVENT_DESTROY_CAIRO_SURFACE -: rdp_plugin.h -
  • remmina_rdp_ui_event_destroy_cairo_surface() : rdp_event.c
  • -
  • REMMINA_RDP_UI_EVENT_UPDATE_SCALE -: rdp_plugin.h +
  • REMMINA_RDP_UI_EVENT_DESTROY_CAIRO_SURFACE +: rdp_plugin.h
  • remmina_rdp_ui_event_update_scale() : rdp_event.c
  • +
  • REMMINA_RDP_UI_EVENT_UPDATE_SCALE +: rdp_plugin.h +
  • REMMINA_RDP_UI_NOCODEC : rdp_plugin.h
  • @@ -4023,8 +4024,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_scrolled_viewport.c
  • remmina_scrolled_viewport_new() -: remmina_scrolled_viewport.h -, remmina_scrolled_viewport.c +: remmina_scrolled_viewport.c +, remmina_scrolled_viewport.h
  • remmina_scrolled_viewport_remove_motion() : remmina_scrolled_viewport.c @@ -4052,8 +4053,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_sftp_plugin.c
  • remmina_sftp_client_confirm_resume() -: remmina_sftp_client.c -, remmina_sftp_client.h +: remmina_sftp_client.h +, remmina_sftp_client.c
  • remmina_sftp_client_destroy() : remmina_sftp_client.c @@ -4065,8 +4066,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_sftp_client.c
  • remmina_sftp_client_new() -: remmina_sftp_client.h -, remmina_sftp_client.c +: remmina_sftp_client.c +, remmina_sftp_client.h
  • remmina_sftp_client_on_canceltask() : remmina_sftp_client.c @@ -4136,28 +4137,28 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_ssh.h
  • remmina_sftp_plugin_register() -: remmina_sftp_plugin.c -, remmina_sftp_plugin.h +: remmina_sftp_plugin.h +, remmina_sftp_plugin.c
  • remmina_sha1_file() -: remmina_utils.c -, remmina_utils.h +: remmina_utils.h +, remmina_utils.c
  • remmina_sodium_init() : remmina_sodium.c , remmina_sodium.h
  • remmina_sodium_pwhash() -: remmina_sodium.c -, remmina_sodium.h +: remmina_sodium.h +, remmina_sodium.c
  • remmina_sodium_pwhash_str() -: remmina_sodium.c -, remmina_sodium.h +: remmina_sodium.h +, remmina_sodium.c
  • remmina_sodium_pwhash_str_verify() -: remmina_sodium.c -, remmina_sodium.h +: remmina_sodium.h +, remmina_sodium.c
  • remmina_ssh_advanced_settings : remmina_ssh_plugin.c @@ -4249,8 +4250,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_ssh.h
  • remmina_ssh_identity_path() -: remmina_ssh.h -, remmina_ssh.c +: remmina_ssh.c +, remmina_ssh.h
  • remmina_ssh_init_from_file() : remmina_ssh.h @@ -4272,19 +4273,19 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_ssh_plugin.h
  • remmina_ssh_plugin_register() -: remmina_ssh_plugin.c -, remmina_ssh_plugin.h +: remmina_ssh_plugin.h +, remmina_ssh_plugin.c
  • remmina_ssh_search_item() : remmina_ssh.c
  • remmina_ssh_set_application_error() -: remmina_ssh.h -, remmina_ssh.c +: remmina_ssh.c +, remmina_ssh.h
  • remmina_ssh_set_error() -: remmina_ssh.h -, remmina_ssh.c +: remmina_ssh.c +, remmina_ssh.h
  • remmina_ssh_set_nodelay() : remmina_ssh.c @@ -4322,12 +4323,12 @@ $(document).ready(function(){initNavTree('globals_r.html','');});
  • REMMINA_SSH_TUNNEL_OPEN : remmina_ssh.h
  • -
  • REMMINA_SSH_TUNNEL_REVERSE -: remmina_ssh.h -
  • remmina_ssh_tunnel_reverse() : remmina_ssh.h
  • +
  • REMMINA_SSH_TUNNEL_REVERSE +: remmina_ssh.h +
  • remmina_ssh_tunnel_terminated() : remmina_ssh.h
  • @@ -4350,8 +4351,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_ssh.c
  • remmina_stats_get_all() -: remmina_stats.h -, remmina_stats.c +: remmina_stats.c +, remmina_stats.h
  • remmina_stats_get_gtk_backend() : remmina_stats.c @@ -4387,19 +4388,19 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_stats.c
  • remmina_string_array_add() -: remmina_string_array.h -, remmina_string_array.c +: remmina_string_array.c +, remmina_string_array.h
  • remmina_string_array_compare_func() : remmina_string_array.c
  • remmina_string_array_find() -: remmina_string_array.c -, remmina_string_array.h +: remmina_string_array.h +, remmina_string_array.c
  • remmina_string_array_free() -: remmina_string_array.c -, remmina_string_array.h +: remmina_string_array.h +, remmina_string_array.c
  • remmina_string_array_intersect() : remmina_string_array.h @@ -4426,8 +4427,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_string_array.h
  • remmina_string_array_sort() -: remmina_string_array.h -, remmina_string_array.c +: remmina_string_array.c +, remmina_string_array.h
  • remmina_string_array_to_string() : remmina_string_array.c @@ -4478,16 +4479,16 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_string_list.c
  • remmina_sysinfo_get_gnome_shell_version() -: remmina_sysinfo.c -, remmina_sysinfo.h +: remmina_sysinfo.h +, remmina_sysinfo.c
  • remmina_sysinfo_get_wm_name() -: remmina_sysinfo.h -, remmina_sysinfo.c +: remmina_sysinfo.c +, remmina_sysinfo.h
  • remmina_sysinfo_is_appindicator_available() -: remmina_sysinfo.h -, remmina_sysinfo.c +: remmina_sysinfo.c +, remmina_sysinfo.h
  • REMMINA_TAB_ALL : remmina_pref.h @@ -4607,28 +4608,28 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_unlock.c
  • remmina_utils_get_etc_release() -: remmina_utils.c -, remmina_utils.h +: remmina_utils.h +, remmina_utils.c
  • remmina_utils_get_kernel_arch() : remmina_utils.c , remmina_utils.h
  • remmina_utils_get_kernel_name() -: remmina_utils.c -, remmina_utils.h +: remmina_utils.h +, remmina_utils.c
  • remmina_utils_get_kernel_release() -: remmina_utils.h -, remmina_utils.c +: remmina_utils.c +, remmina_utils.h
  • remmina_utils_get_lang() -: remmina_utils.c -, remmina_utils.h +: remmina_utils.h +, remmina_utils.c
  • remmina_utils_get_lsb_codename() -: remmina_utils.h -, remmina_utils.c +: remmina_utils.c +, remmina_utils.h
  • remmina_utils_get_lsb_description() : remmina_utils.h @@ -4639,8 +4640,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); , remmina_utils.h
  • remmina_utils_get_lsb_release() -: remmina_utils.c -, remmina_utils.h +: remmina_utils.h +, remmina_utils.c
  • remmina_utils_get_os_info() : remmina_utils.c @@ -4650,20 +4651,20 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_utils.c
  • remmina_utils_string_find() -: remmina_utils.c -, remmina_utils.h +: remmina_utils.h +, remmina_utils.c
  • remmina_utils_string_replace() : remmina_utils.h , remmina_utils.c
  • remmina_utils_string_replace_all() -: remmina_utils.c -, remmina_utils.h +: remmina_utils.h +, remmina_utils.c
  • remmina_utils_string_strip() -: remmina_utils.h -, remmina_utils.c +: remmina_utils.c +, remmina_utils.h
  • remmina_utils_strpos() : remmina_utils.c @@ -4678,12 +4679,12 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_widget_pool.c
  • remmina_widget_pool_count() -: remmina_widget_pool.h -, remmina_widget_pool.c +: remmina_widget_pool.c +, remmina_widget_pool.h
  • remmina_widget_pool_find() -: remmina_widget_pool.c -, remmina_widget_pool.h +: remmina_widget_pool.h +, remmina_widget_pool.c
  • remmina_widget_pool_find_by_window() : remmina_widget_pool.c @@ -4701,8 +4702,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_widget_pool.c
  • remmina_widget_pool_register() -: remmina_widget_pool.h -, remmina_widget_pool.c +: remmina_widget_pool.c +, remmina_widget_pool.h
  • remmina_widget_pool_register_wrapper() : python_wrapper_remmina.c @@ -4774,8 +4775,8 @@ $(document).ready(function(){initNavTree('globals_r.html','');}); : remmina_exec.h
  • RemminaConnectionObject -: rcw.h -, rcw.c +: rcw.c +, rcw.h
  • RemminaConnectionWindow : rcw.h diff --git a/public/navtreedata.js b/public/navtreedata.js index 6bc6af0bb..0d2fc898d 100644 --- a/public/navtreedata.js +++ b/public/navtreedata.js @@ -93,19 +93,19 @@ var NAVTREEINDEX = "rcw_8c.html#a82c93bbb1ab73807b366b86928c37946", "rdp__plugin_8c.html#a18f77c3f0788ca8df08ebc80c72b553f", "remmina__crypt_8c.html#a3fe2fa245d401146adf02a3a8f996ab9", -"remmina__ftp__client_8c.html#a3a2dc5070f06ae0fcd25fbfe1587ab5c", +"remmina__ftp__client_8c.html#a3cb68d802d3c35dff5cee970d3c33bd5", "remmina__main_8c.html#ab203476099a5ad6e889f91c8e05d577d", -"remmina__pref_8c.html#a10b667eb7a100d6ac8d9544697f22743", -"remmina__protocol__widget_8h.html#a2551dd6f53480609596d2695040fba5d", -"remmina__ssh_8c_source.html", -"remmina__utils_8h.html#a2b4dbb0da7c8ba4bd86877097b85d10c", -"struct___remmina_color_pref.html#a8c109e8479617a5e6da0fcaccf511c60", -"struct___remmina_plugin_service.html#a46433bff9d6f3ea25b67115031e94e9b", -"struct___remmina_pref.html#a994425a04b78282ff40a05580cc9355c", -"struct___remmina_s_s_h.html", -"structmpchanger__params.html#a098952d194a183d4a505aa065797864b", -"structrf__context.html#acee2095e72fb2428c498f62e21800026", -"www__plugin_8c.html#ae38b4f2efc412b6256221d9a33a03cd4" +"remmina__pref_8c.html#a0dd25f5b3a055b936a5fa327bc71f19c", +"remmina__protocol__widget_8h.html#a2506e80d482c34532d0e534856452069", +"remmina__ssh_8c.html#af39f90e2343e62348226aed0d7496dda", +"remmina__utils_8h.html#a116e7cd4565386fe531d3a6d1a3d3730", +"struct___remmina_color_pref.html#a675a8004488715429fa540dffb330d49", +"struct___remmina_plugin_service.html#a4558dbff70064da3de58a6d684611fad", +"struct___remmina_pref.html#a97ad6670df5c399df233f0a74f5c148f", +"struct___remmina_s_f_t_p_client_class.html#ac7786b1cfca2fcc92c85f10e4939f80d", +"structmpchanger__params.html#a00a888f26c1609e064367bb5095c71f4", +"structrf__context.html#acacad775c2c168f900deaa6c90481319", +"www__plugin_8c.html#adb58ee650d75d952dd5802fbba9e9b0e" ]; var SYNCONMSG = 'click to disable panel synchronisation'; diff --git a/public/navtreeindex10.js b/public/navtreeindex10.js index 31b94d6fe..44d0957e2 100644 --- a/public/navtreeindex10.js +++ b/public/navtreeindex10.js @@ -1,5 +1,6 @@ var NAVTREEINDEX10 = { +"remmina__ssh_8c.html#af39f90e2343e62348226aed0d7496dda":[61,0,133,19], "remmina__ssh_8c_source.html":[61,0,133], "remmina__ssh_8h.html":[61,0,134], "remmina__ssh_8h.html#a09bd4aee40b6e8d6ba8ffaa84dc95330":[61,0,134,21], @@ -248,6 +249,5 @@ var NAVTREEINDEX10 = "remmina__utils_8c.html#aff7d3597f23cae366973218cc01a2ae8":[61,0,149,4], "remmina__utils_8c_source.html":[61,0,149], "remmina__utils_8h.html":[61,0,150], -"remmina__utils_8h.html#a0f10e190a6dd212fcb0cf36ce81c8324":[61,0,150,5], -"remmina__utils_8h.html#a116e7cd4565386fe531d3a6d1a3d3730":[61,0,150,2] +"remmina__utils_8h.html#a0f10e190a6dd212fcb0cf36ce81c8324":[61,0,150,5] }; diff --git a/public/navtreeindex11.js b/public/navtreeindex11.js index 8367910df..4c1181147 100644 --- a/public/navtreeindex11.js +++ b/public/navtreeindex11.js @@ -1,5 +1,6 @@ var NAVTREEINDEX11 = { +"remmina__utils_8h.html#a116e7cd4565386fe531d3a6d1a3d3730":[61,0,150,2], "remmina__utils_8h.html#a2b4dbb0da7c8ba4bd86877097b85d10c":[61,0,150,6], "remmina__utils_8h.html#a3ce53eeb3b090f86cfcdbce3e7cf71be":[61,0,150,11], "remmina__utils_8h.html#a54cee350c4ecc6e77af835c4ba90df4c":[61,0,150,1], @@ -248,6 +249,5 @@ var NAVTREEINDEX11 = "struct___remmina_color_pref.html#a3f12bdb761d7c3ee02c0871aa423bcd1":[60,0,15,17], "struct___remmina_color_pref.html#a4ad947d133d2aa2c94756aacb5031e79":[60,0,15,7], "struct___remmina_color_pref.html#a5ae99dc78a80baa14e0407983077c500":[60,0,15,18], -"struct___remmina_color_pref.html#a5d92875f0034e5fc3d360d97d5992bd4":[60,0,15,15], -"struct___remmina_color_pref.html#a675a8004488715429fa540dffb330d49":[60,0,15,0] +"struct___remmina_color_pref.html#a5d92875f0034e5fc3d360d97d5992bd4":[60,0,15,15] }; diff --git a/public/navtreeindex12.js b/public/navtreeindex12.js index 317daed52..a46b74cac 100644 --- a/public/navtreeindex12.js +++ b/public/navtreeindex12.js @@ -1,5 +1,6 @@ var NAVTREEINDEX12 = { +"struct___remmina_color_pref.html#a675a8004488715429fa540dffb330d49":[60,0,15,0], "struct___remmina_color_pref.html#a8c109e8479617a5e6da0fcaccf511c60":[60,0,15,8], "struct___remmina_color_pref.html#a8d7f02ac9b6890ad675b702708bc4af9":[60,0,15,13], "struct___remmina_color_pref.html#aa495bd5170c952a7dccff4e2504f5867":[60,0,15,20], @@ -248,6 +249,5 @@ var NAVTREEINDEX12 = "struct___remmina_plugin_service.html#a40855f4643654a7f2a88f72008ea0b5e":[60,0,43,90], "struct___remmina_plugin_service.html#a42ca6bc7a62f91efdba93cde19b347ce":[60,0,43,121], "struct___remmina_plugin_service.html#a434bf35a11eea8a5b653ffd8c7823d84":[60,0,43,97], -"struct___remmina_plugin_service.html#a45416583767fafcac3fe3a9ac50d400f":[60,0,43,104], -"struct___remmina_plugin_service.html#a4558dbff70064da3de58a6d684611fad":[60,0,43,67] +"struct___remmina_plugin_service.html#a45416583767fafcac3fe3a9ac50d400f":[60,0,43,104] }; diff --git a/public/navtreeindex13.js b/public/navtreeindex13.js index a71c2ca64..57a6e2d56 100644 --- a/public/navtreeindex13.js +++ b/public/navtreeindex13.js @@ -1,5 +1,6 @@ var NAVTREEINDEX13 = { +"struct___remmina_plugin_service.html#a4558dbff70064da3de58a6d684611fad":[60,0,43,67], "struct___remmina_plugin_service.html#a46433bff9d6f3ea25b67115031e94e9b":[60,0,43,89], "struct___remmina_plugin_service.html#a48651c1147371e7e9069eb1fd06a9e4f":[60,0,43,3], "struct___remmina_plugin_service.html#a4880fb57479708bc1cb47bf6b4dcabc3":[60,0,43,14], @@ -248,6 +249,5 @@ var NAVTREEINDEX13 = "struct___remmina_pref.html#a901034949132f369eb34c4f1ded3a0a6":[60,0,54,84], "struct___remmina_pref.html#a90e0cfac442b9e50e0f4857b3ff74255":[60,0,54,83], "struct___remmina_pref.html#a920221c2f304bfa278d0944bbbb6e011":[60,0,54,10], -"struct___remmina_pref.html#a9258f6c3c18f14b4abb148aa43e6bc0e":[60,0,54,22], -"struct___remmina_pref.html#a97ad6670df5c399df233f0a74f5c148f":[60,0,54,19] +"struct___remmina_pref.html#a9258f6c3c18f14b4abb148aa43e6bc0e":[60,0,54,22] }; diff --git a/public/navtreeindex14.js b/public/navtreeindex14.js index db8a2da10..eb50753be 100644 --- a/public/navtreeindex14.js +++ b/public/navtreeindex14.js @@ -1,5 +1,6 @@ var NAVTREEINDEX14 = { +"struct___remmina_pref.html#a97ad6670df5c399df233f0a74f5c148f":[60,0,54,19], "struct___remmina_pref.html#a994425a04b78282ff40a05580cc9355c":[60,0,54,29], "struct___remmina_pref.html#a999b74e3aab2e7fbc4431e803511b568":[60,0,54,4], "struct___remmina_pref.html#a99a34af002da68036758fab3ceb08259":[60,0,54,46], @@ -248,6 +249,5 @@ var NAVTREEINDEX14 = "struct___remmina_s_f_t_p_client.html#a95d95acad60636dd6c45ca93620d1f5b":[60,0,70,4], "struct___remmina_s_f_t_p_client.html#ab74654f5e47c939e1098c183a582023c":[60,0,70,2], "struct___remmina_s_f_t_p_client.html#ad6c612bb5172905eb63bfd5b672e1875":[60,0,70,5], -"struct___remmina_s_f_t_p_client_class.html":[60,0,71], -"struct___remmina_s_f_t_p_client_class.html#ac7786b1cfca2fcc92c85f10e4939f80d":[60,0,71,0] +"struct___remmina_s_f_t_p_client_class.html":[60,0,71] }; diff --git a/public/navtreeindex15.js b/public/navtreeindex15.js index 510b7b79d..5fb00df1f 100644 --- a/public/navtreeindex15.js +++ b/public/navtreeindex15.js @@ -1,5 +1,6 @@ var NAVTREEINDEX15 = { +"struct___remmina_s_f_t_p_client_class.html#ac7786b1cfca2fcc92c85f10e4939f80d":[60,0,71,0], "struct___remmina_s_s_h.html":[60,0,72], "struct___remmina_s_s_h.html#a0b35a5a573abb5e8b8a27a91434a00a5":[60,0,72,4], "struct___remmina_s_s_h.html#a0b3e071eb2c6011efdcea3f65f8e7fa0":[60,0,72,5], @@ -248,6 +249,5 @@ var NAVTREEINDEX15 = "structlsb__distro__info.html":[60,0,86], "structlsb__distro__info.html#a251763a49054183774e2082595537e47":[60,0,86,0], "structlsb__distro__info.html#a7aba92d963bcaed1a5dda7b7be4fa6d7":[60,0,86,1], -"structmpchanger__params.html":[60,0,87], -"structmpchanger__params.html#a00a888f26c1609e064367bb5095c71f4":[60,0,87,13] +"structmpchanger__params.html":[60,0,87] }; diff --git a/public/navtreeindex16.js b/public/navtreeindex16.js index 3c5b47b78..0355bb987 100644 --- a/public/navtreeindex16.js +++ b/public/navtreeindex16.js @@ -1,5 +1,6 @@ var NAVTREEINDEX16 = { +"structmpchanger__params.html#a00a888f26c1609e064367bb5095c71f4":[60,0,87,13], "structmpchanger__params.html#a098952d194a183d4a505aa065797864b":[60,0,87,16], "structmpchanger__params.html#a170ffe7965540ab152a4a95945482c87":[60,0,87,20], "structmpchanger__params.html#a3cb4141ca61b0b9a5584239386dbbe46":[60,0,87,17], @@ -248,6 +249,5 @@ var NAVTREEINDEX16 = "structrf__context.html#aa79909e0ac140a3404151a40bed6a6ec":[60,0,113,34], "structrf__context.html#aafce196b029d2578151275acd07ccb82":[60,0,113,24], "structrf__context.html#ab5ffc4d8ba9d3d8a298414dc8e4efd2a":[60,0,113,30], -"structrf__context.html#ac1f3330674d320c9d0ae408c551be6b8":[60,0,113,50], -"structrf__context.html#acacad775c2c168f900deaa6c90481319":[60,0,113,51] +"structrf__context.html#ac1f3330674d320c9d0ae408c551be6b8":[60,0,113,50] }; diff --git a/public/navtreeindex17.js b/public/navtreeindex17.js index 98cafb3a9..8c0bb5b58 100644 --- a/public/navtreeindex17.js +++ b/public/navtreeindex17.js @@ -1,5 +1,6 @@ var NAVTREEINDEX17 = { +"structrf__context.html#acacad775c2c168f900deaa6c90481319":[60,0,113,51], "structrf__context.html#acee2095e72fb2428c498f62e21800026":[60,0,113,15], "structrf__context.html#ad06c1d1a2295fbdf455df0250dfb2523":[60,0,113,9], "structrf__context.html#ad4ea260ce64d09deea422b9067ee70b4":[60,0,113,25], @@ -248,6 +249,5 @@ var NAVTREEINDEX17 = "www__plugin_8c.html#aab3ceb1ae095823fcbee98ce2811b374":[61,0,169,7], "www__plugin_8c.html#ab0a82693798a5534d8657ba9f7634057":[61,0,169,15], "www__plugin_8c.html#abc7a556e81fb1152b1e9bc68406b983f":[61,0,169,12], -"www__plugin_8c.html#ac6b72af8913086b2ec590a675473f2a1":[61,0,169,23], -"www__plugin_8c.html#adb58ee650d75d952dd5802fbba9e9b0e":[61,0,169,9] +"www__plugin_8c.html#ac6b72af8913086b2ec590a675473f2a1":[61,0,169,23] }; diff --git a/public/navtreeindex18.js b/public/navtreeindex18.js index 4f50b0866..7ac88aeb8 100644 --- a/public/navtreeindex18.js +++ b/public/navtreeindex18.js @@ -1,5 +1,6 @@ var NAVTREEINDEX18 = { +"www__plugin_8c.html#adb58ee650d75d952dd5802fbba9e9b0e":[61,0,169,9], "www__plugin_8c.html#ae38b4f2efc412b6256221d9a33a03cd4":[61,0,169,19], "www__plugin_8c.html#ae6ccaf3df9ea3201521eb62dd9943b00":[61,0,169,11], "www__plugin_8c.html#ae8ced85169ca68aae1ed7f14b488e5b8":[61,0,169,25], diff --git a/public/navtreeindex5.js b/public/navtreeindex5.js index 1cc2529d5..f5bd10c34 100644 --- a/public/navtreeindex5.js +++ b/public/navtreeindex5.js @@ -155,7 +155,6 @@ var NAVTREEINDEX5 = "remmina__file__editor_8c.html#a57224f3f69f04f398de563b71be6b18e":[61,0,80,41], "remmina__file__editor_8c.html#a5ea3f796c3a46aeb01b2f13f4a3d40a9":[61,0,80,47], "remmina__file__editor_8c.html#a6415f73260076747c4f933af7f9f4b38":[61,0,80,6], -"remmina__file__editor_8c.html#a65b38bc13546d3d890624a79b080ffe9":[61,0,80,53], "remmina__file__editor_8c.html#a6eb0bcee764064d6a7dd84c015d9ed4f":[61,0,80,24], "remmina__file__editor_8c.html#a727f967cf81d4af3f953046b0c4cf08d":[61,0,80,19], "remmina__file__editor_8c.html#a73b8581fd1fd77532b748d91a2951f25":[61,0,80,37], @@ -174,7 +173,7 @@ var NAVTREEINDEX5 = "remmina__file__editor_8c.html#aa5c50852f8569f075eec5d5db30c2ebf":[61,0,80,32], "remmina__file__editor_8c.html#aa9345cfe3fb32d326b652e96ee55eaea":[61,0,80,34], "remmina__file__editor_8c.html#aaa55ab55c6806aef6765eb01577365f3":[61,0,80,36], -"remmina__file__editor_8c.html#aadf4d0ab51fe09231b48d4a2939564f7":[61,0,80,54], +"remmina__file__editor_8c.html#aadf4d0ab51fe09231b48d4a2939564f7":[61,0,80,53], "remmina__file__editor_8c.html#ab563344276cbcdf0fcea05b0b64c7aeb":[61,0,80,35], "remmina__file__editor_8c.html#ab5d28ebef67a21099e99268bd6fa04aa":[61,0,80,9], "remmina__file__editor_8c.html#ab6e562792eb63ec43ed7f9a4b6687c23":[61,0,80,20], @@ -249,5 +248,6 @@ var NAVTREEINDEX5 = "remmina__ftp__client_8c.html#a2aaef09531b1694c183a5ba530fcc2fa":[61,0,86,45], "remmina__ftp__client_8c.html#a2e39a69f60d38b46bc603df0ae368aed":[61,0,86,21], "remmina__ftp__client_8c.html#a33e4993b60c36eae89a6a0a943d28141":[61,0,86,43], -"remmina__ftp__client_8c.html#a3872b49a2c0bea73d51d0500c5cee488":[61,0,86,16] +"remmina__ftp__client_8c.html#a3872b49a2c0bea73d51d0500c5cee488":[61,0,86,16], +"remmina__ftp__client_8c.html#a3a2dc5070f06ae0fcd25fbfe1587ab5c":[61,0,86,33] }; diff --git a/public/navtreeindex6.js b/public/navtreeindex6.js index f43d999fb..152931c29 100644 --- a/public/navtreeindex6.js +++ b/public/navtreeindex6.js @@ -1,6 +1,5 @@ var NAVTREEINDEX6 = { -"remmina__ftp__client_8c.html#a3a2dc5070f06ae0fcd25fbfe1587ab5c":[61,0,86,33], "remmina__ftp__client_8c.html#a3cb68d802d3c35dff5cee970d3c33bd5":[61,0,86,61], "remmina__ftp__client_8c.html#a437dba2fc4f44f119501e9b53c688dd1":[61,0,86,25], "remmina__ftp__client_8c.html#a49d1fee26f8c7fb210b46d83f92b08e2":[61,0,86,13], @@ -210,14 +209,14 @@ var NAVTREEINDEX6 = "remmina__main_8c.html#a3c5043279b5d98d4d08635d33402ea66":[61,0,94,81], "remmina__main_8c.html#a3d60de4c121cae0c82e60b13873073db":[61,0,94,62], "remmina__main_8c.html#a40493bb60c169e53e2e08a0d0a808302":[61,0,94,63], -"remmina__main_8c.html#a4477897686d091d6f57e7f9401674a8c":[61,0,94,85], +"remmina__main_8c.html#a4477897686d091d6f57e7f9401674a8c":[61,0,94,86], "remmina__main_8c.html#a44eb44c6391f53a19c6f1fdf9a39a8c1":[61,0,94,47], "remmina__main_8c.html#a4a4733c243f20c3ffc27105003f5e30e":[61,0,94,16], "remmina__main_8c.html#a4b4f0bbdb9e487d6c3809e8a57dc1d1c":[61,0,94,61], "remmina__main_8c.html#a51880fc109db6457a5d0fc543c2deaf2":[61,0,94,77], "remmina__main_8c.html#a52cc21537ff003b9d0fbdb9040c811af":[61,0,94,52], "remmina__main_8c.html#a5445e5568a6fc04d08b620829a59334a":[61,0,94,44], -"remmina__main_8c.html#a5ae0372dafe41f96a09097c07d1b270a":[61,0,94,86], +"remmina__main_8c.html#a5ae0372dafe41f96a09097c07d1b270a":[61,0,94,87], "remmina__main_8c.html#a5db4436cc72b9d5ea3e498f8519efecc":[61,0,94,55], "remmina__main_8c.html#a627eb26ab02f0093365ed6b10dab0320":[61,0,94,34], "remmina__main_8c.html#a6a466d0b07944e619bd9b0e473c8a5bd":[61,0,94,18], @@ -235,10 +234,10 @@ var NAVTREEINDEX6 = "remmina__main_8c.html#a847424fdb97ffe35d060409d4d738497":[61,0,94,30], "remmina__main_8c.html#a85aa313453e0ecaa17bcce233973998d":[61,0,94,11], "remmina__main_8c.html#a861de52d1b5ec54591d0592de6289d79":[61,0,94,68], -"remmina__main_8c.html#a8ccd8303ada6e26880504fc58812fbda":[61,0,94,90], -"remmina__main_8c.html#a8ebbcba2c07af0938b3c29e316747d12":[61,0,94,92], +"remmina__main_8c.html#a8ccd8303ada6e26880504fc58812fbda":[61,0,94,91], +"remmina__main_8c.html#a8ebbcba2c07af0938b3c29e316747d12":[61,0,94,93], "remmina__main_8c.html#a91f22c2834ac7f38d201d8d678f8c57b":[61,0,94,39], -"remmina__main_8c.html#a923b3e2712d969eb59d9291e99f933e8":[61,0,94,87], +"remmina__main_8c.html#a923b3e2712d969eb59d9291e99f933e8":[61,0,94,88], "remmina__main_8c.html#a95532ac6d110eeeb2e41d4b2a329797c":[61,0,94,14], "remmina__main_8c.html#a9896df7a92402b5a61e58420235c515a":[61,0,94,59], "remmina__main_8c.html#a9e60326026d7de56882bc83c0084fd12":[61,0,94,13], @@ -247,7 +246,8 @@ var NAVTREEINDEX6 = "remmina__main_8c.html#aa4d9b76d32fa500f4b9f39a19e4eaaf2":[61,0,94,66], "remmina__main_8c.html#aac0bb51159be042fecab0103e73a54dc":[61,0,94,38], "remmina__main_8c.html#aac3aa116a8d8b527f1aa61b7395b4b32":[61,0,94,54], -"remmina__main_8c.html#aace9ecdd0b74d392ad6ed541bd605c1c":[61,0,94,89], +"remmina__main_8c.html#aac3fe305e456dfa7bb55aa2f057e8cb0":[61,0,94,85], +"remmina__main_8c.html#aace9ecdd0b74d392ad6ed541bd605c1c":[61,0,94,90], "remmina__main_8c.html#ab08aae433b625c3a84330630fe2bd2d5":[61,0,94,83], "remmina__main_8c.html#ab0d22f0e3571eb80886acb0c68005800":[61,0,94,23] }; diff --git a/public/navtreeindex7.js b/public/navtreeindex7.js index a2e5b45ea..632e2ccb4 100644 --- a/public/navtreeindex7.js +++ b/public/navtreeindex7.js @@ -2,7 +2,7 @@ var NAVTREEINDEX7 = { "remmina__main_8c.html#ab203476099a5ad6e889f91c8e05d577d":[61,0,94,60], "remmina__main_8c.html#ab2a1a54320992fb796850ffbd6a63589":[61,0,94,82], -"remmina__main_8c.html#ab7c680e1f6ffeef21cb928a083d36d89":[61,0,94,91], +"remmina__main_8c.html#ab7c680e1f6ffeef21cb928a083d36d89":[61,0,94,92], "remmina__main_8c.html#ab98d51c96a87fddaa2d5d6d4614bafa8":[61,0,94,53], "remmina__main_8c.html#aba1a89a2400c5cc8373c6bd34602ac10":[61,0,94,21], "remmina__main_8c.html#abcf8bd8ca57b389264ff9739a61efdc1":[61,0,94,51], @@ -20,7 +20,7 @@ var NAVTREEINDEX7 = "remmina__main_8c.html#aea426b2e8fc03f963bb2b98cb8649adf":[61,0,94,37], "remmina__main_8c.html#aeb74f36e5fd58ceab9f13a184bfb2029":[61,0,94,64], "remmina__main_8c.html#af129aea3f5f3ec56b061187a81d43e4c":[61,0,94,79], -"remmina__main_8c.html#af146cc1f982c98a9c8a5ac43cc1508f3":[61,0,94,88], +"remmina__main_8c.html#af146cc1f982c98a9c8a5ac43cc1508f3":[61,0,94,89], "remmina__main_8c.html#af14b1942a754d7b2f5c10266208ebe01":[61,0,94,35], "remmina__main_8c.html#af51fc7233eb2397a5074ba37b5c5275f":[61,0,94,71], "remmina__main_8c.html#af56bada711b2fc9c50af83b8b62dfe8b":[61,0,94,49], @@ -41,7 +41,7 @@ var NAVTREEINDEX7 = "remmina__main_8h.html#a4d2d08c3fed3f72ea7f4c0600fec7ed5":[61,0,95,31], "remmina__main_8h.html#a52cc21537ff003b9d0fbdb9040c811af":[61,0,95,21], "remmina__main_8h.html#a5445e5568a6fc04d08b620829a59334a":[61,0,95,13], -"remmina__main_8h.html#a5ae0372dafe41f96a09097c07d1b270a":[61,0,95,36], +"remmina__main_8h.html#a5ae0372dafe41f96a09097c07d1b270a":[61,0,95,37], "remmina__main_8h.html#a5db4436cc72b9d5ea3e498f8519efecc":[61,0,95,24], "remmina__main_8h.html#a6b30ed832369f3a7153aa63f98873c9d":[61,0,95,15], "remmina__main_8h.html#a6ed9f6a588a2d9e3a6cf6884c8d07f92":[61,0,95,12], @@ -52,6 +52,7 @@ var NAVTREEINDEX7 = "remmina__main_8h.html#a9896df7a92402b5a61e58420235c515a":[61,0,95,28], "remmina__main_8h.html#aac0bb51159be042fecab0103e73a54dc":[61,0,95,7], "remmina__main_8h.html#aac3aa116a8d8b527f1aa61b7395b4b32":[61,0,95,23], +"remmina__main_8h.html#aac3fe305e456dfa7bb55aa2f057e8cb0":[61,0,95,36], "remmina__main_8h.html#ab203476099a5ad6e889f91c8e05d577d":[61,0,95,29], "remmina__main_8h.html#ab2a1a54320992fb796850ffbd6a63589":[61,0,95,34], "remmina__main_8h.html#ab98d51c96a87fddaa2d5d6d4614bafa8":[61,0,95,22], @@ -248,6 +249,5 @@ var NAVTREEINDEX7 = "remmina__plugin__native_8h_source.html":[61,0,114], "remmina__pref_8c.html":[61,0,115], "remmina__pref_8c.html#a0208d5dc8197423da67e5967aafb7a05":[61,0,115,7], -"remmina__pref_8c.html#a0296a8f5b359547a0aa4cbffb914edd3":[61,0,115,6], -"remmina__pref_8c.html#a0dd25f5b3a055b936a5fa327bc71f19c":[61,0,115,19] +"remmina__pref_8c.html#a0296a8f5b359547a0aa4cbffb914edd3":[61,0,115,6] }; diff --git a/public/navtreeindex8.js b/public/navtreeindex8.js index d2da6d94a..32265d7b5 100644 --- a/public/navtreeindex8.js +++ b/public/navtreeindex8.js @@ -1,5 +1,6 @@ var NAVTREEINDEX8 = { +"remmina__pref_8c.html#a0dd25f5b3a055b936a5fa327bc71f19c":[61,0,115,19], "remmina__pref_8c.html#a10b667eb7a100d6ac8d9544697f22743":[61,0,115,28], "remmina__pref_8c.html#a12e52ee4ab89912280605e36ee069267":[61,0,115,9], "remmina__pref_8c.html#a1a695b64e75d6f49de220dc777e57714":[61,0,115,14], @@ -248,6 +249,5 @@ var NAVTREEINDEX8 = "remmina__protocol__widget_8h.html#a1585ea6908dd5c0a9b0f47d409916435":[61,0,120,39], "remmina__protocol__widget_8h.html#a172fa9cf2ce196c9846a3e47ea9036b4":[61,0,120,77], "remmina__protocol__widget_8h.html#a1cae52cad394f317c712eb4fd709d261":[61,0,120,72], -"remmina__protocol__widget_8h.html#a2067c19b160eb43bddda6c6c6e8d6045":[61,0,120,35], -"remmina__protocol__widget_8h.html#a2506e80d482c34532d0e534856452069":[61,0,120,22] +"remmina__protocol__widget_8h.html#a2067c19b160eb43bddda6c6c6e8d6045":[61,0,120,35] }; diff --git a/public/navtreeindex9.js b/public/navtreeindex9.js index 160cfe6da..c916661c6 100644 --- a/public/navtreeindex9.js +++ b/public/navtreeindex9.js @@ -1,5 +1,6 @@ var NAVTREEINDEX9 = { +"remmina__protocol__widget_8h.html#a2506e80d482c34532d0e534856452069":[61,0,120,22], "remmina__protocol__widget_8h.html#a2551dd6f53480609596d2695040fba5d":[61,0,120,78], "remmina__protocol__widget_8h.html#a25bcb2ae99449624fed6f770218e3d25":[61,0,120,20], "remmina__protocol__widget_8h.html#a262d75d6b535bd8c623e607805db4084":[61,0,120,50], @@ -248,6 +249,5 @@ var NAVTREEINDEX9 = "remmina__ssh_8c.html#ab8f07d5ab2ee8aa8423a11808b6cb100":[61,0,133,26], "remmina__ssh_8c.html#abc556f0a4335083436f6e19c204fa553":[61,0,133,21], "remmina__ssh_8c.html#ad6f3f5c196175412049af0c440414e65":[61,0,133,7], -"remmina__ssh_8c.html#adfe0e9338fec4a1c03677595c15514d1":[61,0,133,18], -"remmina__ssh_8c.html#af39f90e2343e62348226aed0d7496dda":[61,0,133,19] +"remmina__ssh_8c.html#adfe0e9338fec4a1c03677595c15514d1":[61,0,133,18] }; diff --git a/public/rcw_8c_source.html b/public/rcw_8c_source.html index 3f5c049bc..2cddfcc68 100644 --- a/public/rcw_8c_source.html +++ b/public/rcw_8c_source.html @@ -117,7 +117,7 @@ $(document).ready(function(){initNavTree('rcw_8c_source.html','');});
    gchar * remmina_pref_file
    Definition: rcw.c:78
    static void rcw_toolbar_fullscreen(GtkToolItem *toggle, RemminaConnectionWindow *cnnwin)
    Definition: rcw.c:1351
    static void rcw_on_switch_page(GtkNotebook *notebook, GtkWidget *newpage, guint page_num, RemminaConnectionWindow *cnnwin)
    Definition: rcw.c:3653
    -
    GtkWindow * remmina_main_get_window()
    +
    GtkWindow * remmina_main_get_window()
    gint remmina_protocol_widget_get_width(RemminaProtocolWidget *gp)
    static gboolean rcw_hostkey_func(RemminaProtocolWidget *gp, guint keyval, gboolean release)
    Definition: rcw.c:4053
    void remmina_scrolled_viewport_remove_motion(RemminaScrolledViewport *gsv)
    @@ -168,7 +168,7 @@ $(document).ready(function(){initNavTree('rcw_8c_source.html','');}); -
    void remmina_message_panel_focus_auth_entry(RemminaMessagePanel *mp)
    +
    void remmina_message_panel_focus_auth_entry(RemminaMessagePanel *mp)
    static void rcw_scaler_keep_aspect(GtkWidget *widget, RemminaConnectionWindow *cnnwin)
    Definition: rcw.c:1494
    static void set_label_selectable(gpointer data, gpointer user_data)
    Definition: rcw.c:4452
    static gboolean rcw_tb_drag_drop(GtkWidget *widget, GdkDragContext *context, gint x, gint y, guint time, gpointer user_data)
    Definition: rcw.c:786
    @@ -386,7 +386,7 @@ $(document).ready(function(){initNavTree('rcw_8c_source.html','');});
    static void rcw_toolbar_screenshot(GtkToolItem *toggle, RemminaConnectionWindow *cnnwin)
    Definition: rcw.c:2135
    RemminaConnectionWindow * cnnwin
    Definition: rcw.c:163
    -
    void remmina_message_panel_setup_message(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    +
    void remmina_message_panel_setup_message(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    gboolean kioskmode
    Definition: remmina.c:87
    void remmina_application_condexit(RemminaCondExitType why)
    Definition: remmina_exec.c:123
    void remmina_protocol_widget_set_expand(RemminaProtocolWidget *gp, gboolean expand)
    @@ -426,7 +426,7 @@ $(document).ready(function(){initNavTree('rcw_8c_source.html','');});
    static void rcw_toolbar_duplicate(GtkToolItem *toggle, RemminaConnectionWindow *cnnwin)
    Definition: rcw.c:2122
    void rcw_grab_focus(RemminaConnectionWindow *cnnwin)
    Definition: rcw.c:3441
    gboolean dark_theme
    Definition: remmina_pref.h:149
    -
    RemminaMessagePanel * remmina_message_panel_new()
    +
    RemminaMessagePanel * remmina_message_panel_new()
    static void rcw_scaler_option_popdown(GtkWidget *widget, RemminaConnectionWindow *cnnwin)
    Definition: rcw.c:1468
    gboolean save_view_mode
    Definition: remmina_pref.h:140
    diff --git a/public/remmina__exec_8c_source.html b/public/remmina__exec_8c_source.html index 611522931..6a40a2732 100644 --- a/public/remmina__exec_8c_source.html +++ b/public/remmina__exec_8c_source.html @@ -89,7 +89,7 @@ $(document).ready(function(){initNavTree('remmina__exec_8c_source.html','');}); Go to the documentation of this file.
    1 /*
    2  * Remmina - The GTK+ Remote Desktop Client
    3  * Copyright (C) 2010 Vic Lee
    4  * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
    5  * Copyright (C) 2016-2023 Antenore Gatta, Giovanni Panozzo
    6  *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    15  * GNU General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
    20  * Boston, MA 02110-1301, USA.
    21  *
    22  * In addition, as a special exception, the copyright holders give
    23  * permission to link the code of portions of this program with the
    24  * OpenSSL library under certain conditions as described in each
    25  * individual source file, and distribute linked combinations
    26  * including the two.
    27  * You must obey the GNU General Public License in all respects
    28  * for all of the code used other than OpenSSL. * If you modify
    29  * file(s) with this exception, you may extend this exception to your
    30  * version of the file(s), but you are not obligated to do so. * If you
    31  * do not wish to do so, delete this exception statement from your
    32  * version. * If you delete this exception statement from all source
    33  * files in the program, then also delete it here.
    34  *
    35  */
    36 
    37 #include "config.h"
    38 #include "buildflags.h"
    39 #include <glib/gi18n.h>
    40 #include <stdlib.h>
    41 #include "remmina.h"
    42 #include "remmina_main.h"
    43 #include "remmina_log.h"
    44 #include "remmina_pref.h"
    45 #include "remmina_widget_pool.h"
    46 #include "remmina_unlock.h"
    47 #include "remmina_pref_dialog.h"
    48 #include "remmina_file.h"
    49 #include "remmina_file_manager.h"
    50 #include "remmina_file_editor.h"
    51 #include "rcw.h"
    52 #include "remmina_about.h"
    53 #include "remmina_plugin_manager.h"
    54 #include "remmina_exec.h"
    56 #include "remmina_file_manager.h"
    57 #include "remmina_crypt.h"
    58 
    59 #include "remmina_icon.h"
    60 
    61 #ifdef SNAP_BUILD
    62 # define ISSNAP "- SNAP Build -"
    63 #else
    64 # define ISSNAP "-"
    65 #endif
    66 
    67 static gboolean cb_closewidget(GtkWidget *widget, gpointer data)
    68 {
    69  TRACE_CALL(__func__);
    70  /* The correct way to close a rcw is to send
    71  * it a "delete-event" signal. Simply destroying it will not close
    72  * all network connections */
    73  if (REMMINA_IS_CONNECTION_WINDOW(widget))
    74  return rcw_delete(RCW(widget));
    75  return TRUE;
    76 }
    77 
    79 {
    80  static const gchar build_config[] =
    81  "Build configuration: " BUILD_CONFIG "\n"
    82  "Build type: " BUILD_TYPE "\n"
    83  "CFLAGS: " CFLAGS "\n"
    84  "Compiler: " COMPILER_ID ", " COMPILER_VERSION "\n"
    85  "Target architecture: " TARGET_ARCH "\n";
    86  return build_config;
    87 }
    88 
    90 {
    91  TRACE_CALL(__func__);
    92 
    93  /* Save main window state/position */
    95 
    96  /* Delete all widgets, main window not included */
    98 
    99 #ifdef HAVE_LIBAPPINDICATOR
    100  /* Remove systray menu */
    102 #endif
    103 
    104  /* close/destroy main window struct and window */
    106 
    107  /* Exit from Remmina */
    108  g_application_quit(g_application_get_default());
    109 }
    110 
    111 static gboolean disable_rcw_delete_confirm_cb(GtkWidget *widget, gpointer data)
    112 {
    113  TRACE_CALL(__func__);
    115 
    116  if (REMMINA_IS_CONNECTION_WINDOW(widget)) {
    117  rcw = (RemminaConnectionWindow*)widget;
    119  }
    120  return TRUE;
    121 }
    122 
    124 {
    125  TRACE_CALL(__func__);
    126 
    127  /* Exit remmina only if there are no interesting windows left:
    128  * no main window, no systray menu, no connection window.
    129  * This function is usually called after a disconnection */
    130 
    131  switch (why) {
    133  // A connection has disconnected, should we exit remmina ?
    136  break;
    138  /* If we are in Kiosk mode, we just exit */
    139  if (kioskmode && kioskmode == TRUE)
    141  // Main window has been deleted
    144  break;
    146  // Quit command has been sent from main window or appindicator/systray menu
    147  // quit means QUIT.
    150  break;
    151  }
    152 }
    153 
    154 
    155 static void newline_remove(char *s)
    156 {
    157  char c;
    158  while((c = *s) != 0 && c != '\r' && c != '\n')
    159  s++;
    160  *s = 0;
    161 }
    162 
    163 /* used for commandline parameter --update-profile X --set-option Y --set-option Z
    164  * return a status code for exit()
    165  */
    166 int remmina_exec_set_setting(gchar *profilefilename, gchar **settings)
    167 {
    168  RemminaFile *remminafile;
    169  int i;
    170  gchar **tk, *value = NULL;
    171  char *line = NULL;
    172  size_t len = 0;
    173  ssize_t read;
    174  gboolean abort = FALSE;
    175 
    176  remminafile = remmina_file_manager_load_file(profilefilename);
    177 
    178  if (!remminafile) {
    179  g_print("Unable to open profile file %s\n", profilefilename);
    180  return 2;
    181  }
    182 
    183  for(i = 0; settings[i] != NULL && !abort; i++) {
    184  if (strlen(settings[i]) > 0) {
    185  tk = g_strsplit(settings[i], "=", 2);
    186  if (tk[1] == NULL) {
    187  read = getline(&line, &len, stdin);
    188  if (read > 0) {
    189  newline_remove(line);
    190  value = line;
    191  } else {
    192  g_print("Error: an extra line of standard input is needed\n");
    193  abort = TRUE;
    194  }
    195  } else
    196  value = tk[1];
    197  remmina_file_set_string(remminafile, tk[0], value);
    198  g_strfreev(tk);
    199  }
    200  }
    201 
    202  if (line) free(line);
    203 
    204  if (!abort) remmina_file_save(remminafile);
    205 
    206  return 0;
    207 
    208 }
    209 
    210 static void remmina_exec_autostart_cb(RemminaFile *remminafile, gpointer user_data)
    211 {
    212  TRACE_CALL(__func__);
    213 
    214  if (remmina_file_get_int(remminafile, "enable-autostart", FALSE)) {
    215  REMMINA_DEBUG ("Profile %s is set to autostart", remminafile->filename);
    216  rcw_open_from_filename(remminafile->filename);
    217  }
    218 
    219 }
    220 
    221 static void remmina_exec_connect(const gchar *data)
    222 {
    223  TRACE_CALL(__func__);
    224 
    225  gchar *protocol;
    226  gchar **protocolserver;
    227  gchar *server;
    228  RemminaFile *remminafile;
    229  gchar **userat;
    230  gchar **userpass;
    231  gchar *user;
    232  gchar *password;
    233  gchar **domainuser;
    234  gchar **serverquery;
    235  gchar **querystring;
    236  gchar **querystringpart;
    237  gchar **querystringpartkv;
    238  gchar *value;
    239  gchar *temp;
    240  GError *error = NULL;
    241 
    242  protocol = NULL;
    243  if (strncmp("rdp://", data, 6) == 0 || strncmp("RDP://", data, 6) == 0)
    244  protocol = "RDP";
    245  else if (strncmp("vnc://", data, 6) == 0 || strncmp("VNC://", data, 6) == 0)
    246  protocol = "VNC";
    247  else if (strncmp("ssh://", data, 6) == 0 || strncmp("SSH://", data, 6) == 0)
    248  protocol = "SSH";
    249  else if (strncmp("spice://", data, 8) == 0 || strncmp("SPICE://", data, 8) == 0)
    250  protocol = "SPICE";
    251 
    252  if (strncmp("file://", data, 6) == 0) {
    253  gchar *filename = g_filename_from_uri (data, NULL, &error);
    254  if (filename != NULL) {
    255  rcw_open_from_filename(filename);
    256  } else
    257  REMMINA_DEBUG ("Opening URI %s failed with error %s", data, error->message);
    258  g_error_free(error);
    259  return;
    260  }
    261 
    262  if (protocol == NULL) {
    264  return;
    265  }
    266 
    267  protocolserver = g_strsplit(data, "://", 2);
    268  server = g_strdup(protocolserver[1]);
    269 
    270  // Support loading .remmina files using handler
    271  if ((temp = strrchr(server, '.')) != NULL && g_strcmp0(temp + 1, "remmina") == 0) {
    272  g_strfreev(protocolserver);
    273  temp = g_uri_unescape_string(server, NULL);
    274  g_free(server);
    275  server = temp;
    276  rcw_open_from_filename(server);
    277  return;
    278  }
    279 
    280  remminafile = remmina_file_new();
    281 
    282  // Check for username@server
    283  if ((strcmp(protocol, "RDP") == 0 || strcmp(protocol, "VNC") == 0 || strcmp(protocol, "SSH") == 0) && strstr(server, "@") != NULL) {
    284  userat = g_strsplit(server, "@", 2);
    285 
    286  // Check for username:password
    287  if (strstr(userat[0], ":") != NULL) {
    288  userpass = g_strsplit(userat[0], ":", 2);
    289  user = g_uri_unescape_string(userpass[0], NULL);
    290  password = g_uri_unescape_string(userpass[1], NULL);
    291 
    292  // Try to decrypt the password field if it contains =
    293  temp = password != NULL && strrchr(password, '=') != NULL ? remmina_crypt_decrypt(password) : NULL;
    294  if (temp != NULL) {
    295  g_free(password);
    296  password = temp;
    297  }
    298  remmina_file_set_string(remminafile, "password", password);
    299  g_free(password);
    300  g_strfreev(userpass);
    301  } else {
    302  user = g_uri_unescape_string(userat[0], NULL);
    303  }
    304 
    305  // Check for domain\user for RDP connections
    306  if (strcmp(protocol, "RDP") == 0 && strstr(user, "\\") != NULL) {
    307  domainuser = g_strsplit(user, "\\", 2);
    308  remmina_file_set_string(remminafile, "domain", domainuser[0]);
    309  g_free(user);
    310  user = g_strdup(domainuser[1]);
    311  }
    312 
    313  remmina_file_set_string(remminafile, "username", user);
    314  g_free(user);
    315  g_free(server);
    316  server = g_strdup(userat[1]);
    317  g_strfreev(userat);
    318  }
    319 
    320  if (strcmp(protocol, "VNC") == 0 && strstr(server, "?") != NULL) {
    321  // https://tools.ietf.org/html/rfc7869
    322  // VncUsername, VncPassword and ColorLevel supported for vnc-params
    323 
    324  // Check for query string parameters
    325  serverquery = g_strsplit(server, "?", 2);
    326  querystring = g_strsplit(serverquery[1], "&", -1);
    327  for (querystringpart = querystring; *querystringpart; querystringpart++) {
    328  if (strstr(*querystringpart, "=") == NULL)
    329  continue;
    330  querystringpartkv = g_strsplit(*querystringpart, "=", 2);
    331  value = g_uri_unescape_string(querystringpartkv[1], NULL);
    332  if (strcmp(querystringpartkv[0], "VncPassword") == 0) {
    333  // Try to decrypt password field if it contains =
    334  temp = value != NULL && strrchr(value, '=') != NULL ? remmina_crypt_decrypt(value) : NULL;
    335  if (temp != NULL) {
    336  g_free(value);
    337  value = temp;
    338  }
    339  remmina_file_set_string(remminafile, "password", value);
    340  } else if (strcmp(querystringpartkv[0], "VncUsername") == 0) {
    341  remmina_file_set_string(remminafile, "username", value);
    342  } else if (strcmp(querystringpartkv[0], "ColorLevel") == 0) {
    343  remmina_file_set_string(remminafile, "colordepth", value);
    344  }
    345  g_free(value);
    346  g_strfreev(querystringpartkv);
    347  }
    348  g_strfreev(querystring);
    349  g_free(server);
    350  server = g_strdup(serverquery[0]);
    351  g_strfreev(serverquery);
    352  }
    353 
    354  // Unescape server
    355  temp = g_uri_unescape_string(server, NULL);
    356  g_free(server);
    357  server = temp;
    358 
    359  remmina_file_set_string(remminafile, "server", server);
    360  remmina_file_set_string(remminafile, "name", server);
    361  remmina_file_set_string(remminafile, "sound", "off");
    362  remmina_file_set_string(remminafile, "protocol", protocol);
    363  g_free(server);
    364  g_strfreev(protocolserver);
    365  rcw_open_from_file(remminafile);
    366 }
    367 
    368 void remmina_exec_command(RemminaCommandType command, const gchar* data)
    369 {
    370  TRACE_CALL(__func__);
    371  gchar *s1;
    372  gchar *s2;
    373  gchar *temp;
    374  GtkWidget *widget;
    375  GtkWindow *mainwindow;
    376  GtkWidget *prefdialog;
    377  RemminaEntryPlugin *plugin;
    378  int i;
    379  int ch;
    380  mainwindow = remmina_main_get_window();
    381 
    382  switch (command) {
    385  break;
    386 
    388  if (mainwindow) {
    389  gtk_window_present(mainwindow);
    390  gtk_window_deiconify(GTK_WINDOW(mainwindow));
    391  }else {
    392  widget = remmina_main_new();
    393  gtk_widget_show(widget);
    394  }
    395  break;
    396 
    398  if (remmina_pref_get_boolean("use_primary_password")
    399  && remmina_unlock_new(mainwindow) == 0)
    400  break;
    401  prefdialog = remmina_pref_dialog_get_dialog();
    402  if (prefdialog) {
    403  gtk_window_present(GTK_WINDOW(prefdialog));
    404  gtk_window_deiconify(GTK_WINDOW(prefdialog));
    405  }else {
    406  /* Create a new preference dialog */
    407  widget = remmina_pref_dialog_new(atoi(data), NULL);
    408  gtk_widget_show(widget);
    409  }
    410  break;
    411 
    412  case REMMINA_COMMAND_NEW:
    413  if (remmina_pref_get_boolean("lock_edit")
    414  && remmina_pref_get_boolean("use_primary_password"))
    415  if (remmina_unlock_new(mainwindow) == 0)
    416  break;
    417  s1 = (data ? strchr(data, ',') : NULL);
    418  if (s1) {
    419  s1 = g_strdup(data);
    420  s2 = strchr(s1, ',');
    421  *s2++ = '\0';
    422  widget = remmina_file_editor_new_full(s2, s1);
    423  g_free(s1);
    424  }else {
    425  widget = remmina_file_editor_new_full(NULL, data);
    426  }
    427  gtk_widget_show(widget);
    428  break;
    429 
    431  REMMINA_DEBUG ("Initiating connection");
    436  if (remmina_pref_get_boolean("lock_connect")
    437  && remmina_pref_get_boolean("use_primary_password"))
    438  if (remmina_unlock_new(mainwindow) == 0)
    439  break;
    440  remmina_exec_connect(data);
    441  break;
    442 
    444  if (remmina_pref_get_boolean("lock_edit")
    445  && remmina_pref_get_boolean("use_primary_password"))
    446  if (remmina_unlock_new(mainwindow) == 0)
    447  break;
    449  if (widget)
    450  gtk_widget_show(widget);
    451  break;
    452 
    454  remmina_about_open(NULL);
    455  break;
    456 
    458  mainwindow = remmina_main_get_window();
    459  if (mainwindow) {
    460  remmina_about_open(NULL);
    461  }else {
    462  g_print("%s %s %s (git %s)\n", g_get_application_name(), ISSNAP, VERSION, REMMINA_GIT_REVISION);
    463  /* As we do not use the "handle-local-options" signal, we have to exit Remmina */
    465  }
    466 
    467  break;
    468 
    470  mainwindow = remmina_main_get_window();
    471  if (mainwindow) {
    472  /* Show th widget with the list of plugins and versions */
    473  remmina_plugin_manager_show(mainwindow);
    474  }else {
    475  g_print("\n%s %s %s (git %s)\n\n", g_get_application_name(), ISSNAP, VERSION, REMMINA_GIT_REVISION);
    476 
    478  g_print("\n%s\n", remmina_exec_get_build_config());
    480  }
    481 
    482  break;
    483 
    484 
    487  if (plugin) {
    488  plugin->entry_func(plugin);
    489  }else {
    490  widget = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
    491  _("Plugin %s is not registered."), data);
    492  g_signal_connect(G_OBJECT(widget), "response", G_CALLBACK(gtk_widget_destroy), NULL);
    493  gtk_widget_show(widget);
    495  }
    496  break;
    497 
    499  i = 0;
    500  g_print("Enter the password you want to encrypt: ");
    501  temp = (char *)g_malloc(255 * sizeof(char));
    502  while ((ch = getchar()) != EOF && ch != '\n') {
    503  if (i < 254) {
    504  temp[i] = ch;
    505  i++;
    506  }
    507  }
    508  temp[i] = '\0';
    509  s1 = remmina_crypt_encrypt(temp);
    510  s2 = g_uri_escape_string(s1, NULL, TRUE);
    511  g_print("\nEncrypted password: %s\n\n", s1);
    512  g_print("Usage:\n");
    513  g_print("rdp://username:%s@server\n", s1);
    514  g_print("vnc://username:%s@server\n", s1);
    515  g_print("vnc://server?VncUsername=user\\&VncPassword=%s\n", s2);
    516  g_free(s1);
    517  g_free(s2);
    518  g_free(temp);
    520  break;
    521 
    525  break;
    526 
    527  default:
    528  break;
    529  }
    530 }
    int remmina_exec_set_setting(gchar *profilefilename, gchar **settings)
    Definition: remmina_exec.c:166
    RemminaCondExitType
    Definition: remmina_exec.h:58
    -
    GtkWindow * remmina_main_get_window()
    +
    GtkWindow * remmina_main_get_window()
    gchar * remmina_crypt_decrypt(const gchar *str)
    @@ -104,8 +104,8 @@ $(document).ready(function(){initNavTree('remmina__exec_8c_source.html','');});
    gboolean remmina_icon_is_available(void)
    Determine whenever the Remmina icon is available.
    Definition: remmina_icon.c:318
    -
    GtkWidget * remmina_file_editor_new_full(const gchar *server, const gchar *protocol)
    -
    GtkWidget * remmina_main_new(void)
    +
    GtkWidget * remmina_file_editor_new_full(const gchar *server, const gchar *protocol)
    +
    GtkWidget * remmina_main_new(void)
    void remmina_main_save_before_destroy()
    Save the Remmina Main Window size and the expanded group before to close Remmina. ...
    Definition: remmina_main.c:180
    const gchar * remmina_exec_get_build_config(void)
    Definition: remmina_exec.c:78
    @@ -129,7 +129,7 @@ $(document).ready(function(){initNavTree('remmina__exec_8c_source.html','');});
    void remmina_exec_exitremmina()
    Definition: remmina_exec.c:89
    gboolean remmina_pref_get_boolean(const gchar *key)
    -
    GtkWidget * remmina_file_editor_new_from_filename(const gchar *filename)
    +
    GtkWidget * remmina_file_editor_new_from_filename(const gchar *filename)
    void remmina_main_destroy()
    Definition: remmina_main.c:193
    RemminaFile * remmina_file_new(void)
    Definition: remmina_file.c:93
    diff --git a/public/remmina__file_8c_source.html b/public/remmina__file_8c_source.html index 415e66860..7412f6e50 100644 --- a/public/remmina__file_8c_source.html +++ b/public/remmina__file_8c_source.html @@ -122,7 +122,7 @@ $(document).ready(function(){initNavTree('remmina__file_8c_source.html','');});
    gchar * remmina_file_format_properties(RemminaFile *remminafile, const gchar *setting)
    Definition: remmina_file.c:561
    const RemminaProtocolSetting * find_protocol_setting(const gchar *name, RemminaProtocolPlugin *protocol_plugin)
    Definition: remmina_file.c:235
    -
    void remmina_main_update_file_datetime(RemminaFile *file)
    +
    void remmina_main_update_file_datetime(RemminaFile *file)
    const gchar * icon_name_ssh
    Definition: plugin.h:73
    gint remmina_file_get_state_int(RemminaFile *remminafile, const gchar *setting, gint default_value)
    Definition: remmina_file.c:615
    void remmina_file_state_last_success(RemminaFile *remminafile)
    Definition: remmina_file.c:948
    @@ -135,7 +135,7 @@ $(document).ready(function(){initNavTree('remmina__file_8c_source.html','');});
    gchar * remmina_crypt_encrypt(const gchar *str)
    Definition: remmina_crypt.c:93
    gdouble remmina_file_get_state_double(RemminaFile *remminafile, const gchar *setting, gdouble default_value)
    Definition: remmina_file.c:655
    -
    void remmina_main_show_warning_dialog(const gchar *message)
    +
    void remmina_main_show_warning_dialog(const gchar *message)
    void remmina_file_set_int(RemminaFile *remminafile, const gchar *setting, gint value)
    Definition: remmina_file.c:585
    static GKeyFile * remmina_file_get_keyfile(RemminaFile *remminafile)
    Definition: remmina_file.c:680
    diff --git a/public/remmina__file__editor_8c.html b/public/remmina__file__editor_8c.html index b04584269..0f6327ca6 100644 --- a/public/remmina__file__editor_8c.html +++ b/public/remmina__file__editor_8c.html @@ -119,8 +119,6 @@ Functions   static void remmina_file_editor_create_server (RemminaFileEditor *gfe, const RemminaProtocolSetting *setting, GtkWidget *grid, gint row)   -static void remmina_file_toggle_password_view (GtkWidget *widget, gpointer data) -  static GtkWidget * remmina_file_editor_create_password (RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gchar *value, gchar *setting_name)   static void remmina_file_editor_update_resolution (GtkWidget *widget, RemminaFileEditor *gfe) @@ -319,7 +317,7 @@ Variables
    -

    Definition at line 542 of file remmina_file_editor.c.

    +

    Definition at line 527 of file remmina_file_editor.c.

    @@ -377,7 +375,7 @@ Variables
    -

    Definition at line 1864 of file remmina_file_editor.c.

    +

    Definition at line 1849 of file remmina_file_editor.c.

    @@ -433,7 +431,7 @@ Variables
    -

    Definition at line 1314 of file remmina_file_editor.c.

    +

    Definition at line 1299 of file remmina_file_editor.c.

    @@ -461,7 +459,7 @@ Variables
    -

    Definition at line 1091 of file remmina_file_editor.c.

    +

    Definition at line 1076 of file remmina_file_editor.c.

    @@ -529,7 +527,7 @@ Variables
    -

    Definition at line 758 of file remmina_file_editor.c.

    +

    Definition at line 743 of file remmina_file_editor.c.

    @@ -606,7 +604,7 @@ Variables

    Create checkbox + gtk_file_chooser for open files and select folders.

    The code is wrong, because if the checkbox is not active, the value should be set to NULL and remove it from the remmina file. The problem is that this function knows nothing about the remmina file. This should be rewritten in a more generic way Please use REMMINA_PROTOCOL_SETTING_TYPE_TEXT

    -

    Definition at line 786 of file remmina_file_editor.c.

    +

    Definition at line 771 of file remmina_file_editor.c.

    @@ -680,7 +678,7 @@ Variables
    -

    Definition at line 735 of file remmina_file_editor.c.

    +

    Definition at line 720 of file remmina_file_editor.c.

    @@ -760,7 +758,7 @@ Variables
    -

    Definition at line 891 of file remmina_file_editor.c.

    +

    Definition at line 876 of file remmina_file_editor.c.

    @@ -840,7 +838,7 @@ Variables
    -

    Definition at line 849 of file remmina_file_editor.c.

    +

    Definition at line 834 of file remmina_file_editor.c.

    @@ -992,7 +990,7 @@ Variables
    -

    Definition at line 493 of file remmina_file_editor.c.

    +

    Definition at line 478 of file remmina_file_editor.c.

    @@ -1042,7 +1040,7 @@ Variables
    -

    Definition at line 558 of file remmina_file_editor.c.

    +

    Definition at line 543 of file remmina_file_editor.c.

    @@ -1116,7 +1114,7 @@ Variables
    -

    Definition at line 713 of file remmina_file_editor.c.

    +

    Definition at line 698 of file remmina_file_editor.c.

    @@ -1210,7 +1208,7 @@ Variables
    -

    Definition at line 936 of file remmina_file_editor.c.

    +

    Definition at line 921 of file remmina_file_editor.c.

    @@ -1248,7 +1246,7 @@ Variables
    -

    Definition at line 1146 of file remmina_file_editor.c.

    +

    Definition at line 1131 of file remmina_file_editor.c.

    @@ -1316,7 +1314,7 @@ Variables
    -

    Definition at line 671 of file remmina_file_editor.c.

    +

    Definition at line 656 of file remmina_file_editor.c.

    @@ -1396,7 +1394,7 @@ Variables
    -

    Definition at line 637 of file remmina_file_editor.c.

    +

    Definition at line 622 of file remmina_file_editor.c.

    @@ -1464,7 +1462,7 @@ Variables
    -

    Definition at line 680 of file remmina_file_editor.c.

    +

    Definition at line 665 of file remmina_file_editor.c.

    @@ -1550,7 +1548,7 @@ Variables
    -

    Definition at line 838 of file remmina_file_editor.c.

    +

    Definition at line 823 of file remmina_file_editor.c.

    @@ -1588,7 +1586,7 @@ Variables
    -

    Definition at line 1874 of file remmina_file_editor.c.

    +

    Definition at line 1859 of file remmina_file_editor.c.

    @@ -1608,7 +1606,7 @@ Variables
    -

    Definition at line 1891 of file remmina_file_editor.c.

    +

    Definition at line 1876 of file remmina_file_editor.c.

    @@ -1636,7 +1634,7 @@ Variables
    -

    Definition at line 1799 of file remmina_file_editor.c.

    +

    Definition at line 1784 of file remmina_file_editor.c.

    @@ -1684,7 +1682,7 @@ Variables
    -

    Definition at line 824 of file remmina_file_editor.c.

    +

    Definition at line 809 of file remmina_file_editor.c.

    @@ -1728,7 +1726,7 @@ Variables
    -

    Definition at line 1842 of file remmina_file_editor.c.

    +

    Definition at line 1827 of file remmina_file_editor.c.

    @@ -1748,7 +1746,7 @@ Variables
    -

    Definition at line 2034 of file remmina_file_editor.c.

    +

    Definition at line 2019 of file remmina_file_editor.c.

    @@ -1768,7 +1766,7 @@ Variables
    -

    Definition at line 2054 of file remmina_file_editor.c.

    +

    Definition at line 2039 of file remmina_file_editor.c.

    @@ -1788,7 +1786,7 @@ Variables
    -

    Definition at line 1905 of file remmina_file_editor.c.

    +

    Definition at line 1890 of file remmina_file_editor.c.

    @@ -1808,7 +1806,7 @@ Variables
    -

    Definition at line 2073 of file remmina_file_editor.c.

    +

    Definition at line 2058 of file remmina_file_editor.c.

    @@ -1838,7 +1836,7 @@ Variables
    -

    Definition at line 2040 of file remmina_file_editor.c.

    +

    Definition at line 2025 of file remmina_file_editor.c.

    @@ -1876,7 +1874,7 @@ Variables
    -

    Definition at line 1793 of file remmina_file_editor.c.

    +

    Definition at line 1778 of file remmina_file_editor.c.

    @@ -1914,7 +1912,7 @@ Variables
    -

    Definition at line 1744 of file remmina_file_editor.c.

    +

    Definition at line 1729 of file remmina_file_editor.c.

    @@ -1952,7 +1950,7 @@ Variables
    -

    Definition at line 1686 of file remmina_file_editor.c.

    +

    Definition at line 1671 of file remmina_file_editor.c.

    @@ -2028,7 +2026,7 @@ Variables
    -

    Definition at line 1724 of file remmina_file_editor.c.

    +

    Definition at line 1709 of file remmina_file_editor.c.

    @@ -2067,7 +2065,7 @@ Variables

    : Call remmina_file_editor_on_save

    -

    Definition at line 1766 of file remmina_file_editor.c.

    +

    Definition at line 1751 of file remmina_file_editor.c.

    @@ -2105,7 +2103,7 @@ Variables
    -

    Definition at line 1351 of file remmina_file_editor.c.

    +

    Definition at line 1336 of file remmina_file_editor.c.

    @@ -2133,7 +2131,7 @@ Variables
    -

    Definition at line 1395 of file remmina_file_editor.c.

    +

    Definition at line 1380 of file remmina_file_editor.c.

    @@ -2161,7 +2159,7 @@ Variables
    -

    Definition at line 1409 of file remmina_file_editor.c.

    +

    Definition at line 1394 of file remmina_file_editor.c.

    @@ -2338,7 +2336,7 @@ TODO: Responsive text size and line wrap.

    -

    Definition at line 1631 of file remmina_file_editor.c.

    +

    Definition at line 1616 of file remmina_file_editor.c.

    @@ -2376,7 +2374,7 @@ TODO: Responsive text size and line wrap.

    -

    Definition at line 530 of file remmina_file_editor.c.

    +

    Definition at line 515 of file remmina_file_editor.c.

    @@ -2414,7 +2412,7 @@ TODO: Responsive text size and line wrap.

    -

    Definition at line 1535 of file remmina_file_editor.c.

    +

    Definition at line 1520 of file remmina_file_editor.c.

    @@ -2464,7 +2462,7 @@ TODO: Responsive text size and line wrap.

    -

    Definition at line 1457 of file remmina_file_editor.c.

    +

    Definition at line 1442 of file remmina_file_editor.c.

    @@ -2500,44 +2498,6 @@ TODO: Responsive text size and line wrap.

    -
    - - -

    ◆ remmina_file_toggle_password_view()

    - -
    -
    - - - - - -
    - - - - - - - - - - - - - - - - - - -
    static void remmina_file_toggle_password_view (GtkWidget * widget,
    gpointer data 
    )
    -
    -static
    -
    - -

    Definition at line 476 of file remmina_file_editor.c.

    -

    Variable Documentation

    @@ -2562,7 +2522,7 @@ TODO: Responsive text size and line wrap.

    Initial value:
    =
    {
    "0", N_("Password"),
    "1", N_("SSH identity file"),
    "2", N_("SSH agent"),
    "3", N_("Public key (automatic)"),
    "4", N_("Kerberos (GSSAPI)"),
    NULL
    }
    N_("Unable to connect to VNC server")
    Definition: vnc_plugin.c:953
    -

    Definition at line 1135 of file remmina_file_editor.c.

    +

    Definition at line 1120 of file remmina_file_editor.c.

    diff --git a/public/remmina__file__editor_8c.js b/public/remmina__file__editor_8c.js index 6d15e9736..516223861 100644 --- a/public/remmina__file__editor_8c.js +++ b/public/remmina__file__editor_8c.js @@ -53,6 +53,5 @@ var remmina__file__editor_8c = [ "remmina_file_editor_update_settings", "remmina__file__editor_8c.html#ac4aed08e645f690ef347adec9cdbb9b9", null ], [ "remmina_file_editor_validate_settings", "remmina__file__editor_8c.html#a8c1924fd32be943136d147e8dedb3eca", null ], [ "remmina_file_get_double", "remmina__file__editor_8c.html#a471a1f5ab14197b626f84ec3128e87d4", null ], - [ "remmina_file_toggle_password_view", "remmina__file__editor_8c.html#a65b38bc13546d3d890624a79b080ffe9", null ], [ "ssh_tunnel_auth_list", "remmina__file__editor_8c.html#aadf4d0ab51fe09231b48d4a2939564f7", null ] ]; \ No newline at end of file diff --git a/public/remmina__file__editor_8c_source.html b/public/remmina__file__editor_8c_source.html index 1848a5bbe..f69e63829 100644 --- a/public/remmina__file__editor_8c_source.html +++ b/public/remmina__file__editor_8c_source.html @@ -86,7 +86,7 @@ $(document).ready(function(){initNavTree('remmina__file__editor_8c_source.html',
    remmina_file_editor.c
    -Go to the documentation of this file.
    1 /*
    2  * Remmina - The GTK+ Remote Desktop Client
    3  * Copyright (C) 2009-2011 Vic Lee
    4  * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
    5  * Copyright (C) 2016-2023 Antenore Gatta, Giovanni Panozzo
    6  *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    15  * GNU General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
    20  * Boston, MA 02110-1301, USA.
    21  *
    22  * In addition, as a special exception, the copyright holders give
    23  * permission to link the code of portions of this program with the
    24  * OpenSSL library under certain conditions as described in each
    25  * individual source file, and distribute linked combinations
    26  * including the two.
    27  * You must obey the GNU General Public License in all respects
    28  * for all of the code used other than OpenSSL. * If you modify
    29  * file(s) with this exception, you may extend this exception to your
    30  * version of the file(s), but you are not obligated to do so. * If you
    31  * do not wish to do so, delete this exception statement from your
    32  * version. * If you delete this exception statement from all source
    33  * files in the program, then also delete it here.
    34  *
    35  */
    36 
    37 #include <ctype.h>
    38 #include "config.h"
    39 #ifdef HAVE_LIBAVAHI_UI
    40 #include <avahi-ui/avahi-ui.h>
    41 #endif
    42 #include "remmina_public.h"
    43 #include "remmina_pref.h"
    44 #include "rcw.h"
    46 #include "remmina_file.h"
    47 #include "remmina_file_editor.h"
    48 #include "remmina_file_manager.h"
    49 #include "remmina_icon.h"
    50 #include "remmina_main.h"
    51 #include "remmina_plugin_manager.h"
    52 #include "remmina_pref_dialog.h"
    53 #include "remmina_ssh.h"
    54 #include "remmina_string_list.h"
    55 #include "remmina_unlock.h"
    56 #include "remmina_widget_pool.h"
    57 
    58 G_DEFINE_TYPE(RemminaFileEditor, remmina_file_editor, GTK_TYPE_DIALOG)
    59 
    60 static const gchar *server_tips = N_("<big>"
    61  "Supported formats\n"
    62  "• server\n"
    63  "• server[:port]\n"
    64  "VNC additional formats\n"
    65  "• ID:repeater ID number\n"
    66  "• unix:///path/socket.sock"
    67  "</big>");
    68 
    69 static const gchar *cmd_tips = N_("<big>"
    70  "• command in PATH args %h\n"
    71  "• /path/to/foo -options %h %u\n"
    72  "• %h is substituted with the server name\n"
    73  "• %t is substituted with the SSH server name\n"
    74  "• %u is substituted with the username\n"
    75  "• %U is substituted with the SSH username\n"
    76  "• %p is substituted with Remmina profile name\n"
    77  "• %g is substituted with Remmina profile group name\n"
    78  "• %d is substituted with local date and time in ISO 8601 format\n"
    79  "Do not run in background if you want the command to be executed before connecting.\n"
    80  "</big>");
    81 
    82 #ifdef HAVE_LIBSSH
    83 static const gchar *server_tips2 = N_("<big>"
    84  "Supported formats\n"
    85  "• server\n"
    86  "• server[:port]\n"
    87  "• username@server[:port] (SSH protocol only)"
    88  "</big>");
    89 #endif
    90 
    91 struct _RemminaFileEditorPriv {
    92  RemminaFile * remmina_file;
    93  RemminaProtocolPlugin * plugin;
    94  const gchar * avahi_service_type;
    95 
    96  GtkWidget * name_entry;
    97  GtkWidget * labels_entry;
    98  GtkWidget * group_combo;
    99  GtkWidget * protocol_combo;
    100  GtkWidget * save_button;
    101 
    102  GtkWidget * config_box;
    103  GtkWidget * config_scrollable;
    104  GtkWidget * config_viewport;
    105  GtkWidget * config_container;
    106 
    107  GtkWidget * server_combo;
    108  GtkWidget * resolution_iws_radio;
    109  GtkWidget * resolution_auto_radio;
    110  GtkWidget * resolution_custom_radio;
    111  GtkWidget * resolution_custom_combo;
    112  GtkWidget * keymap_combo;
    113 
    114  GtkWidget * behavior_autostart_check;
    115  GtkWidget * behavior_precommand_entry;
    116  GtkWidget * behavior_postcommand_entry;
    117  GtkWidget * behavior_lock_check;
    118 
    119  GtkWidget * ssh_tunnel_enabled_check;
    120  GtkWidget * ssh_tunnel_loopback_check;
    121  GtkWidget * ssh_tunnel_server_default_radio;
    122  GtkWidget * ssh_tunnel_server_custom_radio;
    123  GtkWidget * ssh_tunnel_server_entry;
    124  GtkWidget * ssh_tunnel_auth_agent_radio;
    125  GtkWidget * ssh_tunnel_auth_password_radio;
    126  GtkWidget * ssh_tunnel_auth_password;
    127  GtkWidget * ssh_tunnel_passphrase;
    128  GtkWidget * ssh_tunnel_auth_publickey_radio;
    129  GtkWidget * ssh_tunnel_auth_auto_publickey_radio;
    130  GtkWidget * ssh_tunnel_auth_combo;
    131  GtkWidget * ssh_tunnel_username_entry;
    132  GtkWidget * ssh_tunnel_privatekey_chooser;
    133  GtkWidget * ssh_tunnel_certfile_chooser;
    134 
    135  GHashTable * setting_widgets;
    136 };
    137 
    139 {
    140  TRACE_CALL(__func__);
    141 }
    142 
    159  GtkWidget * failed_widget,
    160  GError * err)
    161 {
    162  if (!err) {
    163  err = NULL; // g_set_error doesn't like overwriting errors.
    164  g_set_error(&err, 1, 1, _("Input is invalid."));
    165  }
    166 
    167  if (!gfe || !failed_widget) {
    168  g_critical("(%s): Parameters RemminaFileEditor 'gfe' or "
    169  "GtkWidget* 'failed_widget' are 'NULL'!",
    170  __func__);
    171  return;
    172  }
    173 
    174  gint widget_width = gtk_widget_get_allocated_width(failed_widget);
    175  gint widget_height = gtk_widget_get_allocated_height(failed_widget);
    176 
    177  GtkWidget *err_label = gtk_label_new("");
    178  GtkWidget *alert_icon = NULL;
    179  GtkWindow *err_window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
    180  GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    181  GdkWindow *window = gtk_widget_get_window(failed_widget);
    182 
    183  GtkAllocation allocation;
    184  gint failed_widget_x, failed_widget_y;
    185 
    186  gchar *markup = g_strdup_printf("<span size='large'>%s</span>", err->message);
    187 
    188  // Setup err_window
    189  gtk_window_set_decorated(err_window, FALSE);
    190  gtk_window_set_type_hint(err_window, GDK_WINDOW_TYPE_HINT_TOOLTIP);
    191  gtk_window_set_default_size(err_window, widget_width, widget_height);
    192  gtk_window_set_title(err_window, "Error");
    193  gtk_window_set_resizable(err_window, TRUE);
    194 
    195  // Move err_window under failed_widget
    196  gtk_window_set_attached_to(err_window, failed_widget);
    197  gtk_window_set_transient_for(err_window, GTK_WINDOW(gfe));
    198  gdk_window_get_origin(GDK_WINDOW(window), &failed_widget_x, &failed_widget_y);
    199  gtk_widget_get_allocation(failed_widget, &allocation);
    200  failed_widget_x += allocation.x;
    201  failed_widget_y += allocation.y + allocation.height;
    202  gtk_window_move(err_window, failed_widget_x, failed_widget_y);
    203 
    204  // Setup label
    205  gtk_label_set_selectable(GTK_LABEL(err_label), FALSE);
    206  gtk_label_set_max_width_chars(GTK_LABEL(err_label), 1);
    207  gtk_widget_set_hexpand(GTK_WIDGET(err_label), TRUE);
    208  gtk_widget_set_vexpand(GTK_WIDGET(err_label), TRUE);
    209  gtk_label_set_ellipsize(GTK_LABEL(err_label), PANGO_ELLIPSIZE_END);
    210  gtk_label_set_line_wrap(GTK_LABEL(err_label), TRUE);
    211  gtk_label_set_line_wrap_mode(GTK_LABEL(err_label), PANGO_WRAP_WORD_CHAR);
    212  gtk_label_set_markup(GTK_LABEL(err_label), markup);
    213 
    214  alert_icon = gtk_image_new_from_icon_name("dialog-warning-symbolic",
    215  GTK_ICON_SIZE_DND);
    216 
    217  // Fill icon and label into a box.
    218  gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(alert_icon), FALSE, FALSE, 0);
    219  gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(err_label), TRUE, TRUE, 5);
    220 
    221  // Attach box to err_window
    222  gtk_container_add(GTK_CONTAINER(err_window), GTK_WIDGET(box));
    223 
    224  // Display everything.
    225  gtk_widget_show_all(GTK_WIDGET(err_window));
    226 
    227  // Mouse click and focus-loss will delete the err_window.
    228  g_signal_connect(G_OBJECT(err_window), "focus-out-event",
    229  G_CALLBACK(gtk_window_close), NULL);
    230  g_signal_connect(G_OBJECT(err_window), "button-press-event",
    231  G_CALLBACK(gtk_window_close), NULL);
    232 }
    233 
    234 #ifdef HAVE_LIBAVAHI_UI
    235 
    236 static void remmina_file_editor_browse_avahi(GtkWidget *button, RemminaFileEditor *gfe)
    237 {
    238  TRACE_CALL(__func__);
    239  GtkWidget *dialog;
    240  gchar *host;
    241 
    242  dialog = aui_service_dialog_new(_("Choose a Remote Desktop Server"),
    243  GTK_WINDOW(gfe),
    244  _("_Cancel"), GTK_RESPONSE_CANCEL,
    245  _("_OK"), GTK_RESPONSE_ACCEPT,
    246  NULL);
    247 
    248  gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(gfe));
    249  aui_service_dialog_set_resolve_service(AUI_SERVICE_DIALOG(dialog), TRUE);
    250  aui_service_dialog_set_resolve_host_name(AUI_SERVICE_DIALOG(dialog), TRUE);
    251  aui_service_dialog_set_browse_service_types(AUI_SERVICE_DIALOG(dialog),
    252  gfe->priv->avahi_service_type, NULL);
    253 
    254  if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
    255  host = g_strdup_printf("[%s]:%i",
    256  aui_service_dialog_get_host_name(AUI_SERVICE_DIALOG(dialog)),
    257  aui_service_dialog_get_port(AUI_SERVICE_DIALOG(dialog)));
    258  } else {
    259  host = NULL;
    260  }
    261  gtk_widget_destroy(dialog);
    262 
    263  if (host) {
    264  gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(gfe->priv->server_combo))), host);
    265  g_free(host);
    266  }
    267 }
    268 #endif
    269 
    270 static void remmina_file_editor_on_realize(GtkWidget *widget, gpointer user_data)
    271 {
    272  TRACE_CALL(__func__);
    273  RemminaFileEditor *gfe;
    274  GtkWidget *defaultwidget;
    275 
    276  gfe = REMMINA_FILE_EDITOR(widget);
    277 
    278  defaultwidget = gfe->priv->server_combo;
    279 
    280  if (defaultwidget) {
    281  if (GTK_IS_EDITABLE(defaultwidget))
    282  gtk_editable_select_region(GTK_EDITABLE(defaultwidget), 0, -1);
    283  gtk_widget_grab_focus(defaultwidget);
    284  }
    285 }
    286 
    287 static void remmina_file_editor_destroy(GtkWidget *widget, gpointer data)
    288 {
    289  TRACE_CALL(__func__);
    290  remmina_file_free(REMMINA_FILE_EDITOR(widget)->priv->remmina_file);
    291  g_hash_table_destroy(REMMINA_FILE_EDITOR(widget)->priv->setting_widgets);
    292  g_free(REMMINA_FILE_EDITOR(widget)->priv);
    293 }
    294 
    295 static void remmina_file_editor_button_on_toggled(GtkToggleButton *togglebutton, GtkWidget *widget)
    296 {
    297  TRACE_CALL(__func__);
    298  gtk_widget_set_sensitive(widget, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton)));
    299 }
    300 
    302 {
    303  TRACE_CALL(__func__);
    304  /* Create the notebook */
    305  gfe->priv->config_container = gtk_notebook_new();
    306  gfe->priv->config_viewport = gtk_viewport_new(NULL, NULL);
    307  gfe->priv->config_scrollable = gtk_scrolled_window_new(NULL, NULL);
    308  gtk_container_set_border_width(GTK_CONTAINER(gfe->priv->config_scrollable), 2);
    309  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gfe->priv->config_scrollable),
    310  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
    311  gtk_widget_show(gfe->priv->config_scrollable);
    312 
    313  gtk_container_add(GTK_CONTAINER(gfe->priv->config_viewport), gfe->priv->config_container);
    314  gtk_container_set_border_width(GTK_CONTAINER(gfe->priv->config_viewport), 2);
    315  gtk_widget_show(gfe->priv->config_viewport);
    316  gtk_container_add(GTK_CONTAINER(gfe->priv->config_scrollable), gfe->priv->config_viewport);
    317  gtk_container_set_border_width(GTK_CONTAINER(gfe->priv->config_container), 2);
    318  gtk_widget_show(gfe->priv->config_container);
    319 
    320  gtk_container_add(GTK_CONTAINER(gfe->priv->config_box), gfe->priv->config_scrollable);
    321 }
    322 
    324  const gchar *stock_id, const gchar *label, gint rows, gint cols)
    325 {
    326  TRACE_CALL(__func__);
    327  GtkWidget *tablabel;
    328  GtkWidget *tabbody;
    329  GtkWidget *grid;
    330  GtkWidget *widget;
    331 
    332  tablabel = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    333  gtk_widget_show(tablabel);
    334 
    335  widget = gtk_image_new_from_icon_name(stock_id, GTK_ICON_SIZE_BUTTON);
    336  gtk_box_pack_start(GTK_BOX(tablabel), widget, FALSE, FALSE, 0);
    337  gtk_widget_show(widget);
    338 
    339  widget = gtk_label_new(label);
    340  gtk_box_pack_start(GTK_BOX(tablabel), widget, FALSE, FALSE, 0);
    341  gtk_widget_show(widget);
    342 
    343  tabbody = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    344  gtk_widget_show(tabbody);
    345  gtk_notebook_append_page(GTK_NOTEBOOK(gfe->priv->config_container), tabbody, tablabel);
    346 
    347  grid = gtk_grid_new();
    348  gtk_widget_show(grid);
    349  gtk_grid_set_row_spacing(GTK_GRID(grid), 8);
    350  gtk_grid_set_column_spacing(GTK_GRID(grid), 8);
    351  gtk_container_set_border_width(GTK_CONTAINER(grid), 15);
    352  gtk_box_pack_start(GTK_BOX(tabbody), grid, FALSE, FALSE, 0);
    353 
    354  return grid;
    355 }
    356 
    357 #ifdef HAVE_LIBSSH
    358 
    360 {
    361  TRACE_CALL(__func__);
    362  gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_server_entry),
    363  gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gfe->priv->ssh_tunnel_enabled_check)) &&
    364  (gfe->priv->ssh_tunnel_server_custom_radio == NULL ||
    365  gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gfe->priv->ssh_tunnel_server_custom_radio))));
    366 }
    367 
    368 static void remmina_file_editor_ssh_tunnel_enabled_check_on_toggled(GtkToggleButton *togglebutton,
    370 {
    371  TRACE_CALL(__func__);
    372  RemminaFileEditorPriv *priv = gfe->priv;
    373  gboolean enabled = TRUE;
    374  gchar *p;
    375  const gchar *cp;
    376  const gchar *s = NULL;
    377 
    378  if (gfe->priv->ssh_tunnel_enabled_check) {
    379  enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gfe->priv->ssh_tunnel_enabled_check));
    380  if (gfe->priv->ssh_tunnel_loopback_check)
    381  gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_loopback_check), enabled);
    382  if (gfe->priv->ssh_tunnel_server_default_radio)
    383  gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_server_default_radio), enabled);
    384  if (gfe->priv->ssh_tunnel_server_custom_radio)
    385  gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_server_custom_radio), enabled);
    387  p = remmina_public_combo_get_active_text(GTK_COMBO_BOX(priv->protocol_combo));
    388  // if (!(g_strcmp0(p, "SFTP") == 0 || g_strcmp0(p, "SSH") == 0)) {
    389  gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_username_entry), enabled);
    390  gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_auth_password), enabled);
    391  gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_auth_combo), enabled);
    392  gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_privatekey_chooser), enabled);
    393  gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_certfile_chooser), enabled);
    394  //}
    395  g_free(p);
    396  }
    397  // remmina_file_editor_ssh_tunnel_auth_publickey_radio_on_toggled(NULL, gfe);
    398  s = remmina_file_get_string(gfe->priv->remmina_file, "ssh_tunnel_privatekey");
    399  if (s)
    400  gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(gfe->priv->ssh_tunnel_privatekey_chooser), s);
    401  s = remmina_file_get_string(gfe->priv->remmina_file, "ssh_tunnel_certfile");
    402  if (s)
    403  gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(gfe->priv->ssh_tunnel_certfile_chooser), s);
    404 
    405  if (gfe->priv->ssh_tunnel_username_entry)
    406  if (enabled && gtk_entry_get_text(GTK_ENTRY(gfe->priv->ssh_tunnel_username_entry))[0] == '\0') {
    407  cp = remmina_file_get_string(priv->remmina_file, "ssh_tunnel_username");
    408  gtk_entry_set_text(GTK_ENTRY(gfe->priv->ssh_tunnel_username_entry), cp ? cp : "");
    409  }
    410 
    411  if (gfe->priv->ssh_tunnel_auth_password) {
    412  if (enabled && gtk_entry_get_text(GTK_ENTRY(gfe->priv->ssh_tunnel_auth_password))[0] == '\0') {
    413  cp = remmina_file_get_string(priv->remmina_file, "ssh_tunnel_password");
    414  gtk_entry_set_text(GTK_ENTRY(gfe->priv->ssh_tunnel_auth_password), cp ? cp : "");
    415  }
    416  }
    417  if (gfe->priv->ssh_tunnel_passphrase) {
    418  if (enabled && gtk_entry_get_text(GTK_ENTRY(gfe->priv->ssh_tunnel_passphrase))[0] == '\0') {
    419  cp = remmina_file_get_string(priv->remmina_file, "ssh_tunnel_passphrase");
    420  gtk_entry_set_text(GTK_ENTRY(gfe->priv->ssh_tunnel_passphrase), cp ? cp : "");
    421  }
    422  }
    423 }
    424 
    425 #endif
    426 
    427 static void remmina_file_editor_create_server(RemminaFileEditor *gfe, const RemminaProtocolSetting *setting, GtkWidget *grid,
    428  gint row)
    429 {
    430  TRACE_CALL(__func__);
    431  RemminaProtocolPlugin *plugin = gfe->priv->plugin;
    432  GtkWidget *widget;
    433 #ifdef HAVE_LIBAVAHI_UI
    434  GtkWidget *hbox;
    435 #endif
    436  gchar *s;
    437 
    438  widget = gtk_label_new(_("Server"));
    439  gtk_widget_show(widget);
    440  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    441  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    442  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, row + 1);
    443 
    444  s = remmina_pref_get_recent(plugin->name);
    445  widget = remmina_public_create_combo_entry(s, remmina_file_get_string(gfe->priv->remmina_file, "server"), TRUE);
    446  gtk_widget_set_hexpand(widget, TRUE);
    447  gtk_widget_show(widget);
    448  gtk_widget_set_tooltip_markup(widget, _(server_tips));
    449  gtk_entry_set_activates_default(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(widget))), TRUE);
    450  gfe->priv->server_combo = widget;
    451  g_free(s);
    452 
    453 #ifdef HAVE_LIBAVAHI_UI
    454  if (setting->opt1) {
    455  gfe->priv->avahi_service_type = (const gchar *)setting->opt1;
    456 
    457  hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    458  gtk_widget_show(hbox);
    459  gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0);
    460 
    461  widget = gtk_button_new_with_label("…");
    462  s = g_strdup_printf(_("Browse the network to find a %s server"), plugin->name);
    463  gtk_widget_set_tooltip_text(widget, s);
    464  g_free(s);
    465  gtk_widget_show(widget);
    466  gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0);
    467  g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_file_editor_browse_avahi), gfe);
    468 
    469  gtk_grid_attach(GTK_GRID(grid), hbox, 1, row, 1, 1);
    470  } else
    471 #endif
    472  {
    473  gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 1, 1);
    474  }
    475 }
    476 static void remmina_file_toggle_password_view(GtkWidget *widget, gpointer data)
    477 {
    478  GtkWindow *mainwindow;
    479  gboolean visible = gtk_entry_get_visibility(GTK_ENTRY(widget));
    480 
    481  mainwindow = remmina_main_get_window();
    482  if (remmina_pref_get_boolean("use_primary_password") && remmina_pref_get_boolean("lock_view_passwords") && remmina_unlock_new(mainwindow) == 0)
    483  return;
    484 
    485  if (visible) {
    486  gtk_entry_set_visibility(GTK_ENTRY(widget), FALSE);
    487  gtk_entry_set_icon_from_icon_name(GTK_ENTRY(widget), GTK_ENTRY_ICON_SECONDARY, "org.remmina.Remmina-password-reveal-symbolic");
    488  } else {
    489  gtk_entry_set_visibility(GTK_ENTRY(widget), TRUE);
    490  gtk_entry_set_icon_from_icon_name(GTK_ENTRY(widget), GTK_ENTRY_ICON_SECONDARY, "org.remmina.Remmina-password-conceal-symbolic");
    491  }
    492 }
    493 static GtkWidget *remmina_file_editor_create_password(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gchar *value, gchar *setting_name)
    494 {
    495  TRACE_CALL(__func__);
    496  GtkWidget *widget;
    497 
    498  widget = gtk_label_new(label);
    499  gtk_widget_show(widget);
    500 #if GTK_CHECK_VERSION(3, 12, 0)
    501  gtk_widget_set_margin_end(widget, 40);
    502 #else
    503  gtk_widget_set_margin_right(widget, 40);
    504 #endif
    505  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    506  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    507  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
    508 
    509  widget = gtk_entry_new();
    510  gtk_widget_show(widget);
    511  gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 1, 1);
    512  gtk_entry_set_max_length(GTK_ENTRY(widget), 0);
    513  gtk_entry_set_visibility(GTK_ENTRY(widget), FALSE);
    514  gtk_widget_set_hexpand(widget, TRUE);
    515  gtk_entry_set_activates_default(GTK_ENTRY(widget), TRUE);
    516  if (setting_name)
    517  gtk_widget_set_name(widget, setting_name);
    518 
    519  if (value)
    520  gtk_entry_set_text(GTK_ENTRY(widget), value);
    521  /* Password view Toogle*/
    522  if (setting_name) {
    523  gtk_entry_set_icon_from_icon_name(GTK_ENTRY(widget), GTK_ENTRY_ICON_SECONDARY, "org.remmina.Remmina-password-reveal-symbolic");
    524  gtk_entry_set_icon_activatable(GTK_ENTRY(widget), GTK_ENTRY_ICON_SECONDARY, TRUE);
    525  g_signal_connect(widget, "icon-press", G_CALLBACK(remmina_file_toggle_password_view), NULL);
    526  }
    527  return widget;
    528 }
    529 
    530 static void remmina_file_editor_update_resolution(GtkWidget *widget, RemminaFileEditor *gfe)
    531 {
    532  TRACE_CALL(__func__);
    533  gchar *res_str;
    534  res_str = g_strdup_printf("%dx%d",
    535  remmina_file_get_int(gfe->priv->remmina_file, "resolution_width", 0),
    536  remmina_file_get_int(gfe->priv->remmina_file, "resolution_height", 0));
    537  remmina_public_load_combo_text_d(gfe->priv->resolution_custom_combo, remmina_pref.resolutions,
    538  res_str, NULL);
    539  g_free(res_str);
    540 }
    541 
    542 static void remmina_file_editor_browse_resolution(GtkWidget *button, RemminaFileEditor *gfe)
    543 {
    544  TRACE_CALL(__func__);
    545 
    546  GtkDialog *dialog = remmina_string_list_new(FALSE, NULL);
    549  remmina_string_list_set_titles(_("Resolutions"), _("Configure the available resolutions"));
    550  gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(gfe));
    551  gtk_dialog_run(dialog);
    552  g_free(remmina_pref.resolutions);
    554  g_signal_connect(G_OBJECT(dialog), "destroy", G_CALLBACK(remmina_file_editor_update_resolution), gfe);
    555  gtk_widget_destroy(GTK_WIDGET(dialog));
    556 }
    557 
    559  GtkWidget *grid, gint row)
    560 {
    561  TRACE_CALL(__func__);
    562  GtkWidget *widget;
    563  GtkWidget *hbox;
    564  int resolution_w, resolution_h;
    565  gchar *res_str;
    567 
    568  res_mode = remmina_file_get_int(gfe->priv->remmina_file, "resolution_mode", RES_INVALID);
    569  resolution_w = remmina_file_get_int(gfe->priv->remmina_file, "resolution_width", -1);
    570  resolution_h = remmina_file_get_int(gfe->priv->remmina_file, "resolution_height", -1);
    571 
    572  /* If resolution_mode is non-existent (-1), then we try to calculate it
    573  * as we did before having resolution_mode */
    574  if (res_mode == RES_INVALID) {
    575  if (resolution_w <= 0 || resolution_h <= 0)
    576  res_mode = RES_USE_INITIAL_WINDOW_SIZE;
    577  else
    578  res_mode = RES_USE_CUSTOM;
    579  }
    580  if (res_mode == RES_USE_CUSTOM)
    581  res_str = g_strdup_printf("%dx%d", resolution_w, resolution_h);
    582  else
    583  res_str = NULL;
    584 
    585  widget = gtk_label_new(_("Resolution"));
    586  gtk_widget_show(widget);
    587  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    588  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    589  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
    590 
    591  hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    592  widget = gtk_radio_button_new_with_label(NULL, _("Use initial window size"));
    593  gtk_widget_show(widget);
    594  gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0);
    595  gfe->priv->resolution_iws_radio = widget;
    596  widget = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(gfe->priv->resolution_iws_radio), _("Use client resolution"));
    597  gtk_widget_show(widget);
    598  gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0);
    599  gfe->priv->resolution_auto_radio = widget;
    600  gtk_grid_attach(GTK_GRID(grid), hbox, 1, row, 1, 1);
    601  gtk_widget_show(hbox);
    602 
    603  hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    604  gtk_widget_show(hbox);
    605  gtk_grid_attach(GTK_GRID(grid), hbox, 1, row + 1, 1, 1);
    606 
    607  widget = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(gfe->priv->resolution_iws_radio), _("Custom"));
    608  gtk_widget_show(widget);
    609  gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0);
    610  gfe->priv->resolution_custom_radio = widget;
    611 
    613  gtk_widget_show(widget);
    614  gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0);
    615  gfe->priv->resolution_custom_combo = widget;
    616 
    617  widget = gtk_button_new_with_label("…");
    618  gtk_widget_show(widget);
    619  gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0);
    620  g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_file_editor_browse_resolution), gfe);
    621 
    622  g_signal_connect(G_OBJECT(gfe->priv->resolution_custom_radio), "toggled",
    623  G_CALLBACK(remmina_file_editor_button_on_toggled), gfe->priv->resolution_custom_combo);
    624 
    625  if (res_mode == RES_USE_CUSTOM)
    626  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gfe->priv->resolution_custom_radio), TRUE);
    627  else if (res_mode == RES_USE_CLIENT)
    628  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gfe->priv->resolution_auto_radio), TRUE);
    629  else
    630  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gfe->priv->resolution_iws_radio), TRUE);
    631 
    632  gtk_widget_set_sensitive(gfe->priv->resolution_custom_combo, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gfe->priv->resolution_custom_radio)));
    633 
    634  g_free(res_str);
    635 }
    636 
    637 static GtkWidget *remmina_file_editor_create_text2(RemminaFileEditor *gfe, GtkWidget *grid,
    638  gint row, gint col, const gchar *label, const gchar *value, gint left,
    639  gint right, gchar *setting_name)
    640 {
    641  TRACE_CALL(__func__);
    642  GtkWidget *widget;
    643 
    644  widget = gtk_label_new(label);
    645  gtk_widget_show(widget);
    646 #if GTK_CHECK_VERSION(3, 12, 0)
    647  gtk_widget_set_margin_start(widget, left);
    648  gtk_widget_set_margin_end(widget, right);
    649 #else
    650  gtk_widget_set_margin_left(widget, left);
    651  gtk_widget_set_margin_right(widget, right);
    652 #endif
    653  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    654  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    655  gtk_grid_attach(GTK_GRID(grid), widget, col, row, 1, 1);
    656 
    657  widget = gtk_entry_new();
    658  gtk_widget_show(widget);
    659  gtk_grid_attach(GTK_GRID(grid), widget, col + 1, row, 1, 1);
    660  gtk_entry_set_max_length(GTK_ENTRY(widget), 300);
    661  gtk_widget_set_hexpand(widget, TRUE);
    662  if (setting_name)
    663  gtk_widget_set_name(widget, setting_name);
    664 
    665  if (value)
    666  gtk_entry_set_text(GTK_ENTRY(widget), value);
    667 
    668  return widget;
    669 }
    670 
    671 static GtkWidget *remmina_file_editor_create_text(RemminaFileEditor *gfe, GtkWidget *grid,
    672  gint row, gint col, const gchar *label, const gchar *value,
    673  gchar *setting_name)
    674 {
    675  TRACE_CALL(__func__);
    676  return remmina_file_editor_create_text2(gfe, grid, row, col, label, value, 0, 40,
    677  setting_name);
    678 }
    679 
    680 static GtkWidget *remmina_file_editor_create_textarea(RemminaFileEditor *gfe, GtkWidget *grid,
    681  gint row, gint col, const gchar *label, const gchar *value,
    682  gchar *setting_name)
    683 {
    684  TRACE_CALL(__func__);
    685  GtkWidget *widget;
    686  GtkTextView *view;
    687  GtkTextBuffer *buffer;
    688  GtkTextIter start;
    689 
    690  widget = gtk_text_view_new();
    691  view = GTK_TEXT_VIEW(widget);
    692  gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view), GTK_WRAP_WORD);
    693  gtk_text_view_set_top_margin(GTK_TEXT_VIEW(view), 20);
    694  gtk_text_view_set_bottom_margin(GTK_TEXT_VIEW(view), 20);
    695  gtk_text_view_set_left_margin(GTK_TEXT_VIEW(view), 20);
    696  gtk_text_view_set_right_margin(GTK_TEXT_VIEW(view), 20);
    697  gtk_text_view_set_monospace(view, TRUE);
    698  if (setting_name)
    699  gtk_widget_set_name(widget, setting_name);
    700  if (value) {
    701  buffer = gtk_text_view_get_buffer(view);
    702  gtk_text_buffer_set_text(buffer, value, -1);
    703  gtk_text_buffer_get_start_iter(buffer, &start);
    704  gtk_text_buffer_place_cursor(buffer, &start);
    705  }
    706  gtk_widget_show(widget);
    707  gtk_widget_set_hexpand(widget, TRUE);
    708  gtk_widget_set_size_request(GTK_WIDGET(view), 320, 300);
    709  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
    710  return widget;
    711 }
    712 
    713 static GtkWidget *remmina_file_editor_create_select(RemminaFileEditor *gfe, GtkWidget *grid,
    714  gint row, gint col, const gchar *label, const gpointer *list,
    715  const gchar *value, gchar *setting_name)
    716 {
    717  TRACE_CALL(__func__);
    718  GtkWidget *widget;
    719 
    720  widget = gtk_label_new(label);
    721  gtk_widget_show(widget);
    722  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    723  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    724  if (setting_name)
    725  gtk_widget_set_name(widget, setting_name);
    726  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
    727 
    728  widget = remmina_public_create_combo_map(list, value, FALSE, gfe->priv->plugin->domain);
    729  gtk_widget_show(widget);
    730  gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 1, 1);
    731 
    732  return widget;
    733 }
    734 
    735 static GtkWidget *remmina_file_editor_create_combo(RemminaFileEditor *gfe, GtkWidget *grid,
    736  gint row, gint col, const gchar *label, const gchar *list,
    737  const gchar *value, gchar *setting_name)
    738 {
    739  TRACE_CALL(__func__);
    740  GtkWidget *widget;
    741 
    742  widget = gtk_label_new(label);
    743  gtk_widget_show(widget);
    744  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    745  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    746  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
    747 
    748  widget = remmina_public_create_combo_entry(list, value, FALSE);
    749  gtk_widget_show(widget);
    750  gtk_widget_set_hexpand(widget, TRUE);
    751  if (setting_name)
    752  gtk_widget_set_name(widget, setting_name);
    753  gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 1, 1);
    754 
    755  return widget;
    756 }
    757 
    758 static GtkWidget *remmina_file_editor_create_check(RemminaFileEditor *gfe, GtkWidget *grid,
    759  gint row, gint top, const gchar *label, gboolean value,
    760  gchar *setting_name)
    761 {
    762  TRACE_CALL(__func__);
    763  GtkWidget *widget;
    764  widget = gtk_check_button_new_with_label(label);
    765  gtk_widget_show(widget);
    766  if (setting_name)
    767  gtk_widget_set_name(widget, setting_name);
    768  gtk_grid_attach(GTK_GRID(grid), widget, top, row, 1, 1);
    769 
    770  if (value)
    771  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
    772 
    773  return widget;
    774 }
    775 
    785 static GtkWidget *
    786 remmina_file_editor_create_chooser(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label,
    787  const gchar *value, gint type, gchar *setting_name)
    788 {
    789  TRACE_CALL(__func__);
    790  GtkWidget *check;
    791  GtkWidget *widget;
    792  GtkWidget *hbox;
    793 
    794  widget = gtk_label_new(label);
    795  gtk_widget_show(widget);
    796  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    797  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    798  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
    799 
    800  hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    801  gtk_widget_show(hbox);
    802  gtk_grid_attach(GTK_GRID(grid), hbox, 1, row, 1, 1);
    803 
    804  check = gtk_check_button_new();
    805  gtk_widget_show(check);
    806  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), (value && value[0] == '/'));
    807  gtk_box_pack_start(GTK_BOX(hbox), check, FALSE, FALSE, 0);
    808 
    809  widget = gtk_file_chooser_button_new(label, type);
    810  if (setting_name)
    811  gtk_widget_set_name(widget, setting_name);
    812  gtk_widget_show(widget);
    813  if (value)
    814  gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(widget), value);
    815  gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0);
    816 
    817  g_signal_connect(G_OBJECT(check), "toggled", G_CALLBACK(remmina_file_editor_button_on_toggled), widget);
    818  remmina_file_editor_button_on_toggled(GTK_TOGGLE_BUTTON(check), widget);
    819 
    820  return widget;
    821 }
    822 
    823 // used to filter out invalid characters for REMMINA_PROTOCOL_SETTING_TYPE_INT
    824 void remmina_file_editor_int_setting_filter(GtkEditable *editable, const gchar *text,
    825  gint length, gint *position, gpointer data)
    826 {
    827  for (int i = 0; i < length; i++) {
    828  if (!isdigit(text[i]) && text[i] != '-') {
    829  g_signal_stop_emission_by_name(G_OBJECT(editable), "insert-text");
    830  return;
    831  }
    832  }
    833 }
    834 
    835 // used to filter out invalid characters for REMMINA_PROTOCOL_SETTING_TYPE_DOUBLE
    836 // '.' and ',' can't be used interchangeably! It depends on the language setting
    837 // of the user.
    838 void remmina_file_editor_double_setting_filter(GtkEditable *editable, const gchar *text,
    839  gint length, gint *position, gpointer data)
    840 {
    841  for (int i = 0; i < length; i++) {
    842  if (!isdigit(text[i]) && text[i] != '-' && text[i] != '.' && text[i] != ',') {
    843  g_signal_stop_emission_by_name(G_OBJECT(editable), "insert-text");
    844  return;
    845  }
    846  }
    847 }
    848 
    849 static GtkWidget *remmina_file_editor_create_int(RemminaFileEditor *gfe, GtkWidget *grid,
    850  gint row, gint col, const gchar *label, const gint value,
    851  gint left, gint right, gchar *setting_name)
    852 {
    853  TRACE_CALL(__func__);
    854  GtkWidget *widget;
    855 
    856  widget = gtk_label_new(label);
    857  gtk_widget_show(widget);
    858 #if GTK_CHECK_VERSION(3, 12, 0)
    859  gtk_widget_set_margin_start(widget, left);
    860  gtk_widget_set_margin_end(widget, right);
    861 #else
    862  gtk_widget_set_margin_left(widget, left);
    863  gtk_widget_set_margin_right(widget, right);
    864 #endif
    865  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    866  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    867  gtk_grid_attach(GTK_GRID(grid), widget, col, row, 1, 1);
    868 
    869  widget = gtk_entry_new();
    870  gtk_widget_show(widget);
    871  gtk_grid_attach(GTK_GRID(grid), widget, col + 1, row, 1, 1);
    872  gtk_entry_set_max_length(GTK_ENTRY(widget), 300);
    873  gtk_widget_set_hexpand(widget, TRUE);
    874  if (setting_name)
    875  gtk_widget_set_name(widget, setting_name);
    876 
    877  // Convert int to str.
    878  int length = snprintf(NULL, 0, "%d", value) + 1; // +1 '\0' byte
    879  char *str = malloc(length);
    880  snprintf(str, length, "%d", value);
    881 
    882  gtk_entry_set_text(GTK_ENTRY(widget), str);
    883  free(str);
    884 
    885  g_signal_connect(G_OBJECT(widget), "insert-text",
    886  G_CALLBACK(remmina_file_editor_int_setting_filter), NULL);
    887 
    888  return widget;
    889 }
    890 
    892  GtkWidget *grid, gint row, gint col,
    893  const gchar *label, gdouble value, gint left,
    894  gint right, gchar *setting_name)
    895 {
    896  TRACE_CALL(__func__);
    897  GtkWidget *widget;
    898 
    899  widget = gtk_label_new(label);
    900  gtk_widget_show(widget);
    901 #if GTK_CHECK_VERSION(3, 12, 0)
    902  gtk_widget_set_margin_start(widget, left);
    903  gtk_widget_set_margin_end(widget, right);
    904 #else
    905  gtk_widget_set_margin_left(widget, left);
    906  gtk_widget_set_margin_right(widget, right);
    907 #endif
    908  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    909  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    910  gtk_grid_attach(GTK_GRID(grid), widget, col, row, 1, 1);
    911 
    912  widget = gtk_entry_new();
    913  gtk_widget_show(widget);
    914  gtk_grid_attach(GTK_GRID(grid), widget, col + 1, row, 1, 1);
    915  gtk_entry_set_max_length(GTK_ENTRY(widget), 300);
    916  gtk_widget_set_hexpand(widget, TRUE);
    917  if (setting_name)
    918  gtk_widget_set_name(widget, setting_name);
    919 
    920  // Convert double to str.
    921  int length = snprintf(NULL, 0, "%.8g", value) + 1; // +1 '\0' byte
    922  char *str = malloc(length);
    923  snprintf(str, length, "%f", value);
    924 
    925  gtk_entry_set_text(GTK_ENTRY(widget), str);
    926  free(str);
    927 
    928  g_signal_connect(G_OBJECT(widget), "insert-text",
    930 
    931  return widget;
    932 }
    933 
    934 gdouble remmina_file_get_double(RemminaFile *remminafile, const gchar *setting, gfloat default_value);
    935 
    936 static void remmina_file_editor_create_settings(RemminaFileEditor *gfe, GtkWidget *grid,
    937  const RemminaProtocolSetting *settings)
    938 {
    939  TRACE_CALL(__func__);
    940  RemminaFileEditorPriv *priv = gfe->priv;
    941  GtkWidget *widget;
    942  gint grid_row = 0;
    943  gint grid_column = 0;
    944  gchar **strarr;
    945  gchar *setting_name;
    946  const gchar *escaped;
    947 
    948  while (settings->type != REMMINA_PROTOCOL_SETTING_TYPE_END) {
    949  setting_name = (gchar *)(remmina_plugin_manager_get_canonical_setting_name(settings));
    950  switch (settings->type) {
    952  remmina_file_editor_create_server(gfe, settings, grid, grid_row);
    953  break;
    954 
    956  widget = remmina_file_editor_create_password(gfe, grid, grid_row, 0,
    957  g_dgettext(priv->plugin->domain, settings->label),
    958  remmina_file_get_string(priv->remmina_file, setting_name),
    959  setting_name);
    960  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    961  grid_row++;
    962  break;
    963 
    965  remmina_file_editor_create_resolution(gfe, settings, grid, grid_row);
    966  grid_row += 1;
    967  break;
    968 
    970  strarr = remmina_pref_keymap_groups();
    971  priv->keymap_combo = remmina_file_editor_create_select(gfe, grid,
    972  grid_row + 1, 0,
    973  _("Keyboard mapping"), (const gpointer *)strarr,
    974  remmina_file_get_string(priv->remmina_file, "keymap"),
    975  setting_name);
    976  g_strfreev(strarr);
    977  grid_row++;
    978  break;
    979 
    981  widget = remmina_file_editor_create_text(gfe, grid, grid_row, 0,
    982  g_dgettext(priv->plugin->domain, settings->label),
    983  remmina_file_get_string(priv->remmina_file, setting_name),
    984  setting_name);
    985  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    986  if (settings->opt2)
    987  gtk_widget_set_tooltip_text(widget, _((const gchar *)settings->opt2));
    988  grid_row++;
    989  break;
    990 
    992  escaped = remmina_file_get_string(priv->remmina_file, setting_name);
    993  escaped = g_uri_unescape_string(escaped, NULL);
    994  widget = remmina_file_editor_create_textarea(gfe, grid, grid_row, 0,
    995  g_dgettext(priv->plugin->domain, settings->label), escaped,
    996  setting_name);
    997  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    998  grid_row++;
    999  break;
    1000 
    1002  widget = remmina_file_editor_create_select(gfe, grid, grid_row, 0,
    1003  g_dgettext(priv->plugin->domain, settings->label),
    1004  (const gpointer *)settings->opt1,
    1005  remmina_file_get_string(priv->remmina_file, setting_name),
    1006  setting_name);
    1007  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    1008  if (settings->opt2)
    1009  gtk_widget_set_tooltip_text(widget, _((const gchar *)settings->opt2));
    1010  break;
    1011 
    1013  widget = remmina_file_editor_create_combo(gfe, grid, grid_row, 0,
    1014  g_dgettext(priv->plugin->domain, settings->label),
    1015  (const gchar *)settings->opt1,
    1016  remmina_file_get_string(priv->remmina_file, setting_name),
    1017  setting_name);
    1018  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    1019  if (settings->opt2)
    1020  gtk_widget_set_tooltip_text(widget, _((const gchar *)settings->opt2));
    1021  break;
    1022 
    1024  widget = remmina_file_editor_create_check(gfe, grid, grid_row, grid_column,
    1025  g_dgettext(priv->plugin->domain, settings->label),
    1026  remmina_file_get_int(priv->remmina_file, setting_name, FALSE),
    1027  setting_name);
    1028  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    1029  if (settings->opt2)
    1030  gtk_widget_set_tooltip_text(widget, _((const gchar *)settings->opt2));
    1031  break;
    1032 
    1034  widget = remmina_file_editor_create_chooser(gfe, grid, grid_row, 0,
    1035  g_dgettext(priv->plugin->domain, settings->label),
    1036  remmina_file_get_string(priv->remmina_file, setting_name),
    1037  GTK_FILE_CHOOSER_ACTION_OPEN, setting_name);
    1038  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    1039  if (settings->opt2)
    1040  gtk_widget_set_tooltip_text(widget, _((const gchar *)settings->opt2));
    1041  break;
    1042 
    1044  widget = remmina_file_editor_create_chooser(gfe, grid, grid_row, 0,
    1045  g_dgettext(priv->plugin->domain, settings->label),
    1046  remmina_file_get_string(priv->remmina_file, setting_name),
    1047  GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
    1048  setting_name);
    1049  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    1050  if (settings->opt2)
    1051  gtk_widget_set_tooltip_text(widget, _((const gchar *)settings->opt2));
    1052  break;
    1054  widget = remmina_file_editor_create_int(gfe, grid, grid_row, 0,
    1055  g_dgettext(priv->plugin->domain, settings->label),
    1056  remmina_file_get_int(priv->remmina_file, setting_name, 0),
    1057  0, 40, setting_name);
    1058  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    1059  if (settings->opt2)
    1060  gtk_widget_set_tooltip_text(widget, _((const gchar *)settings->opt2));
    1061  grid_row++;
    1062  break;
    1064  widget = remmina_file_editor_create_double(gfe, grid, grid_row, 0,
    1065  g_dgettext(priv->plugin->domain, settings->label),
    1066  remmina_file_get_double(priv->remmina_file, setting_name, 0.0f),
    1067  0, 40, setting_name);
    1068  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    1069  if (settings->opt2)
    1070  gtk_widget_set_tooltip_text(widget, _((const gchar *)settings->opt2));
    1071  grid_row++;
    1072  break;
    1073 
    1074  default:
    1075  break;
    1076  }
    1077  /* If the setting wants compactness, move to the next column */
    1078  if (settings->compact)
    1079  grid_column++;
    1080  /* Add a new settings row and move to the first column
    1081  * if the setting doesn’t want the compactness
    1082  * or we already have two columns */
    1083  if (!settings->compact || grid_column > 1) {
    1084  grid_row++;
    1085  grid_column = 0;
    1086  }
    1087  settings++;
    1088  }
    1089 }
    1090 
    1092 {
    1093  TRACE_CALL(__func__);
    1094  RemminaFileEditorPriv *priv = gfe->priv;
    1095  GtkWidget *grid;
    1096  GtkWidget *widget;
    1097  const gchar *cs;
    1098 
    1099  /* The Behavior tab (implementation) */
    1100  grid = remmina_file_editor_create_notebook_tab(gfe, NULL, _("Behavior"), 20, 2);
    1101 
    1102  /* Execute Command frame */
    1103  remmina_public_create_group(GTK_GRID(grid), _("Execute a Command"), 0, 1, 2);
    1104 
    1105  /* PRE connection command */
    1106  cs = remmina_file_get_string(priv->remmina_file, "precommand");
    1107  widget = remmina_file_editor_create_text2(gfe, grid, 2, 0, _("Before connecting"), cs, 24, 26, "precommand");
    1108  priv->behavior_precommand_entry = widget;
    1109  gtk_entry_set_placeholder_text(GTK_ENTRY(widget), _("command %h %u %t %U %p %g --option"));
    1110  gtk_widget_set_tooltip_markup(widget, _(cmd_tips));
    1111 
    1112  /* POST connection command */
    1113  cs = remmina_file_get_string(priv->remmina_file, "postcommand");
    1114  widget = remmina_file_editor_create_text2(gfe, grid, 3, 0, _("After connecting"), cs, 24, 16, "postcommand");
    1115  priv->behavior_postcommand_entry = widget;
    1116  gtk_entry_set_placeholder_text(GTK_ENTRY(widget), _("/path/to/command -opt1 arg %h %u %t -opt2 %U %p %g"));
    1117  gtk_widget_set_tooltip_markup(widget, _(cmd_tips));
    1118 
    1119  /* Startup frame */
    1120  remmina_public_create_group(GTK_GRID(grid), _("Start-up"), 4, 1, 2);
    1121 
    1122  /* Autostart profile option */
    1123  priv->behavior_autostart_check = remmina_file_editor_create_check(gfe, grid, 6, 1, _("Auto-start this profile"),
    1124  remmina_file_get_int(priv->remmina_file, "enable-autostart", FALSE), "enable-autostart");
    1125 
    1126  /* Startup frame */
    1127  remmina_public_create_group(GTK_GRID(grid), _("Connection profile security"), 8, 1, 2);
    1128 
    1129  /* Autostart profile option */
    1130  priv->behavior_lock_check = remmina_file_editor_create_check(gfe, grid, 10, 1, _("Require password to connect or edit the profile"),
    1131  remmina_file_get_int(priv->remmina_file, "profile-lock", FALSE), "profile-lock");
    1132 }
    1133 
    1134 #ifdef HAVE_LIBSSH
    1135 static gpointer ssh_tunnel_auth_list[] =
    1136 {
    1137  "0", N_("Password"),
    1138  "1", N_("SSH identity file"),
    1139  "2", N_("SSH agent"),
    1140  "3", N_("Public key (automatic)"),
    1141  "4", N_("Kerberos (GSSAPI)"),
    1142  NULL
    1143 };
    1144 #endif
    1145 
    1147 {
    1148  TRACE_CALL(__func__);
    1149 #ifdef HAVE_LIBSSH
    1150  RemminaFileEditorPriv *priv = gfe->priv;
    1151  GtkWidget *grid;
    1152  GtkWidget *widget;
    1153  const gchar *cs;
    1154  gchar *s;
    1155  gchar *p;
    1156  gint row = 0;
    1157 
    1158  if (ssh_setting == REMMINA_PROTOCOL_SSH_SETTING_NONE)
    1159  return;
    1160 
    1161  /* The SSH tab (implementation) */
    1162  grid = remmina_file_editor_create_notebook_tab(gfe, NULL,
    1163  _("SSH Tunnel"), 9, 3);
    1164  widget = gtk_toggle_button_new_with_label(_("Enable SSH tunnel"));
    1165  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    1166  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
    1167  g_signal_connect(G_OBJECT(widget), "toggled",
    1169  priv->ssh_tunnel_enabled_check = widget;
    1170 
    1171  widget = gtk_check_button_new_with_label(_("Tunnel via loopback address"));
    1172  gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 2, 1);
    1173  priv->ssh_tunnel_loopback_check = widget;
    1174 
    1175  // 1
    1176  row++;
    1177  /* SSH Server group */
    1178 
    1179  switch (ssh_setting) {
    1181  s = g_strdup_printf(_("Same server at port %i"), DEFAULT_SSH_PORT);
    1182  widget = gtk_radio_button_new_with_label(NULL, s);
    1183  g_free(s);
    1184  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 3, 1);
    1185  priv->ssh_tunnel_server_default_radio = widget;
    1186  // 2
    1187  row++;
    1188 
    1189  widget = gtk_radio_button_new_with_label_from_widget(
    1190  GTK_RADIO_BUTTON(priv->ssh_tunnel_server_default_radio), _("Custom"));
    1191  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
    1192  g_signal_connect(G_OBJECT(widget), "toggled",
    1194  priv->ssh_tunnel_server_custom_radio = widget;
    1195 
    1196  widget = gtk_entry_new();
    1197  gtk_entry_set_max_length(GTK_ENTRY(widget), 100);
    1198  gtk_widget_set_tooltip_markup(widget, _(server_tips2));
    1199  gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 2, 1);
    1200  priv->ssh_tunnel_server_entry = widget;
    1201  // 3
    1202  row++;
    1203  break;
    1204 
    1206  priv->ssh_tunnel_server_default_radio = NULL;
    1207  priv->ssh_tunnel_server_custom_radio = NULL;
    1208 
    1209  priv->ssh_tunnel_server_entry = remmina_file_editor_create_text(gfe, grid, 1, 0,
    1210  _("Server"), NULL, "ssh_reverse_tunnel_server");
    1211  gtk_widget_set_tooltip_markup(priv->ssh_tunnel_server_entry, _(server_tips));
    1212  // 2
    1213  row++;
    1214  break;
    1217  priv->ssh_tunnel_server_default_radio = NULL;
    1218  priv->ssh_tunnel_server_custom_radio = NULL;
    1219  priv->ssh_tunnel_server_entry = NULL;
    1220 
    1221  break;
    1222 
    1223  default:
    1224  break;
    1225  }
    1226 
    1227  /* This is not used? */
    1228  p = remmina_public_combo_get_active_text(GTK_COMBO_BOX(priv->protocol_combo));
    1229  if (ssh_setting == REMMINA_PROTOCOL_SSH_SETTING_SFTP) {
    1230  widget = remmina_file_editor_create_text(gfe, grid, row, 1,
    1231  _("Start-up path"), NULL, "start-up-path");
    1232  cs = remmina_file_get_string(priv->remmina_file, "execpath");
    1233  gtk_entry_set_text(GTK_ENTRY(widget), cs ? cs : "");
    1234  g_hash_table_insert(priv->setting_widgets, "execpath", widget);
    1235  // 2
    1236  row++;
    1237  }
    1238 
    1239  /* SSH Authentication frame */
    1240  remmina_public_create_group(GTK_GRID(grid), _("SSH Authentication"), row, 6, 1);
    1241  // 5
    1242  row += 2;
    1243 
    1244  priv->ssh_tunnel_auth_combo = remmina_file_editor_create_select(gfe, grid, row, 0,
    1245  _("Authentication type"),
    1246  (const gpointer *)ssh_tunnel_auth_list,
    1247  remmina_file_get_string(priv->remmina_file, "ssh_tunnel_auth"), "ssh_tunnel_auth");
    1248  row++;
    1249 
    1250  if (ssh_setting == REMMINA_PROTOCOL_SSH_SETTING_TUNNEL ||
    1252  priv->ssh_tunnel_username_entry =
    1253  remmina_file_editor_create_text(gfe, grid, row, 0,
    1254  _("Username"), NULL, "ssh_tunnel_username");
    1255  // 5
    1256  row++;
    1257  }
    1258 
    1259  widget = remmina_file_editor_create_password(gfe, grid, row, 0,
    1260  _("Password"),
    1261  remmina_file_get_string(priv->remmina_file, "ssh_tunnel_password"),
    1262  "ssh_tunnel_password");
    1263  priv->ssh_tunnel_auth_password = widget;
    1264  row++;
    1265 
    1266  priv->ssh_tunnel_privatekey_chooser = remmina_file_editor_create_chooser(gfe, grid, row, 0,
    1267  _("SSH private key file"),
    1268  remmina_file_get_string(priv->remmina_file, "ssh_tunnel_privatekey"),
    1269  GTK_FILE_CHOOSER_ACTION_OPEN, "ssh_tunnel_privatekey");
    1270  row++;
    1271 
    1272  priv->ssh_tunnel_certfile_chooser = remmina_file_editor_create_chooser(gfe, grid, row, 0,
    1273  _("SSH certificate file"),
    1274  remmina_file_get_string(priv->remmina_file, "ssh_tunnel_certfile"),
    1275  GTK_FILE_CHOOSER_ACTION_OPEN, "ssh_tunnel_certfile");
    1276  row++;
    1277 
    1278  widget = gtk_label_new(_("Password to unlock private key"));
    1279  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
    1280  widget = gtk_entry_new();
    1281  gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 2, 1);
    1282  gtk_entry_set_max_length(GTK_ENTRY(widget), 300);
    1283  gtk_entry_set_visibility(GTK_ENTRY(widget), FALSE);
    1284  gtk_widget_set_hexpand(widget, TRUE);
    1285  priv->ssh_tunnel_passphrase = widget;
    1286  row++;
    1287 
    1288  /* Set the values */
    1289  cs = remmina_file_get_string(priv->remmina_file, "ssh_tunnel_server");
    1290  if (ssh_setting == REMMINA_PROTOCOL_SSH_SETTING_TUNNEL) {
    1291  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->ssh_tunnel_enabled_check),
    1292  remmina_file_get_int(priv->remmina_file, "ssh_tunnel_enabled", FALSE));
    1293  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->ssh_tunnel_loopback_check),
    1294  remmina_file_get_int(priv->remmina_file, "ssh_tunnel_loopback", FALSE));
    1295 
    1296  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cs ? priv->ssh_tunnel_server_custom_radio : priv->ssh_tunnel_server_default_radio), TRUE);
    1297  gtk_entry_set_text(GTK_ENTRY(priv->ssh_tunnel_server_entry),
    1298  cs ? cs : "");
    1299  } else if (ssh_setting == REMMINA_PROTOCOL_SSH_SETTING_REVERSE_TUNNEL) {
    1300  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->ssh_tunnel_enabled_check),
    1301  remmina_file_get_int(priv->remmina_file, "ssh_tunnel_enabled", FALSE));
    1302  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->ssh_tunnel_loopback_check),
    1303  remmina_file_get_int(priv->remmina_file, "ssh_tunnel_loopback", FALSE));
    1304  gtk_entry_set_text(GTK_ENTRY(priv->ssh_tunnel_server_entry),
    1305  cs ? cs : "");
    1306  }
    1307 
    1309  gtk_widget_show_all(grid);
    1310  g_free(p);
    1311 #endif
    1312 }
    1313 
    1315 {
    1316  TRACE_CALL(__func__);
    1317  RemminaFileEditorPriv *priv = gfe->priv;
    1318  GtkWidget *grid;
    1319 
    1320  static const RemminaProtocolSetting notes_settings[] =
    1321  {
    1322  { REMMINA_PROTOCOL_SETTING_TYPE_TEXTAREA, "notes_text", NULL, FALSE, NULL, NULL },
    1323  { REMMINA_PROTOCOL_SETTING_TYPE_END, NULL, NULL, FALSE, NULL, NULL }
    1324  };
    1325 
    1327 
    1328  /* The Basic tab */
    1329  if (priv->plugin->basic_settings) {
    1330  grid = remmina_file_editor_create_notebook_tab(gfe, NULL, _("Basic"), 20, 2);
    1331  remmina_file_editor_create_settings(gfe, grid, priv->plugin->basic_settings);
    1332  }
    1333 
    1334  /* The Advanced tab */
    1335  if (priv->plugin->advanced_settings) {
    1336  grid = remmina_file_editor_create_notebook_tab(gfe, NULL, _("Advanced"), 20, 2);
    1337  remmina_file_editor_create_settings(gfe, grid, priv->plugin->advanced_settings);
    1338  }
    1339 
    1340  /* The Behavior tab */
    1342 
    1343  /* The SSH tab */
    1344  remmina_file_editor_create_ssh_tunnel_tab(gfe, priv->plugin->ssh_setting);
    1345 
    1346  /* Notes tab */
    1347  grid = remmina_file_editor_create_notebook_tab(gfe, NULL, _("Notes"), 1, 1);
    1348  remmina_file_editor_create_settings(gfe, grid, notes_settings);
    1349 }
    1350 
    1352 {
    1353  TRACE_CALL(__func__);
    1354  RemminaFileEditorPriv *priv = gfe->priv;
    1355  gchar *protocol;
    1356 
    1357  if (priv->config_container) {
    1358  gtk_widget_destroy(priv->config_container);
    1359  priv->config_container = NULL;
    1360  gtk_widget_destroy(priv->config_viewport);
    1361  priv->config_viewport = NULL;
    1362  gtk_widget_destroy(priv->config_scrollable);
    1363  priv->config_scrollable = NULL;
    1364  }
    1365 
    1366  priv->server_combo = NULL;
    1367  priv->resolution_iws_radio = NULL;
    1368  priv->resolution_auto_radio = NULL;
    1369  priv->resolution_custom_radio = NULL;
    1370  priv->resolution_custom_combo = NULL;
    1371  priv->keymap_combo = NULL;
    1372 
    1373  priv->ssh_tunnel_enabled_check = NULL;
    1374  priv->ssh_tunnel_loopback_check = NULL;
    1375  priv->ssh_tunnel_server_default_radio = NULL;
    1376  priv->ssh_tunnel_server_custom_radio = NULL;
    1377  priv->ssh_tunnel_server_entry = NULL;
    1378  priv->ssh_tunnel_username_entry = NULL;
    1379  priv->ssh_tunnel_auth_combo = NULL;
    1380  priv->ssh_tunnel_auth_password = NULL;
    1381  priv->ssh_tunnel_privatekey_chooser = NULL;
    1382  priv->ssh_tunnel_certfile_chooser = NULL;
    1383 
    1384  g_hash_table_remove_all(priv->setting_widgets);
    1385 
    1386  protocol = remmina_public_combo_get_active_text(combo);
    1387  if (protocol) {
    1389  protocol);
    1390  g_free(protocol);
    1392  }
    1393 }
    1394 
    1396 {
    1397  TRACE_CALL(__func__);
    1398  RemminaFileEditorPriv *priv = gfe->priv;
    1399 
    1400  remmina_file_set_string(priv->remmina_file, "precommand", gtk_entry_get_text(GTK_ENTRY(priv->behavior_precommand_entry)));
    1401  remmina_file_set_string(priv->remmina_file, "postcommand", gtk_entry_get_text(GTK_ENTRY(priv->behavior_postcommand_entry)));
    1402 
    1403  gboolean autostart_enabled = (priv->behavior_autostart_check ? gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->behavior_autostart_check)) : FALSE);
    1404  remmina_file_set_int(priv->remmina_file, "enable-autostart", autostart_enabled);
    1405  gboolean lock_enabled = (priv->behavior_lock_check ? gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->behavior_lock_check)) : FALSE);
    1406  remmina_file_set_int(priv->remmina_file, "profile-lock", lock_enabled);
    1407 }
    1408 
    1410 {
    1411  TRACE_CALL(__func__);
    1412  RemminaFileEditorPriv *priv = gfe->priv;
    1413  gboolean ssh_tunnel_enabled;
    1414  int ssh_tunnel_auth;
    1415 
    1416  ssh_tunnel_enabled = (priv->ssh_tunnel_enabled_check ? gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->ssh_tunnel_enabled_check)) : FALSE);
    1417  remmina_file_set_int(priv->remmina_file,
    1418  "ssh_tunnel_loopback",
    1419  (priv->ssh_tunnel_loopback_check ? gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->ssh_tunnel_loopback_check)) : FALSE));
    1420  remmina_file_set_int(priv->remmina_file, "ssh_tunnel_enabled", ssh_tunnel_enabled);
    1421  remmina_file_set_string(priv->remmina_file, "ssh_tunnel_auth",
    1422  remmina_public_combo_get_active_text(GTK_COMBO_BOX(priv->ssh_tunnel_auth_combo)));
    1423  remmina_file_set_string(priv->remmina_file, "ssh_tunnel_username",
    1424  (ssh_tunnel_enabled ? gtk_entry_get_text(GTK_ENTRY(priv->ssh_tunnel_username_entry)) : NULL));
    1426  priv->remmina_file,
    1427  "ssh_tunnel_server",
    1428  (ssh_tunnel_enabled && priv->ssh_tunnel_server_entry && (priv->ssh_tunnel_server_custom_radio == NULL || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->ssh_tunnel_server_custom_radio))) ? gtk_entry_get_text(GTK_ENTRY(priv->ssh_tunnel_server_entry)) : NULL));
    1429 
    1430  ssh_tunnel_auth = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->ssh_tunnel_auth_combo));
    1431 
    1433  priv->remmina_file,
    1434  "ssh_tunnel_auth",
    1435  ssh_tunnel_auth);
    1437  priv->remmina_file,
    1438  "ssh_tunnel_privatekey",
    1439  (priv->ssh_tunnel_privatekey_chooser ? gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(priv->ssh_tunnel_privatekey_chooser)) : NULL));
    1440 
    1442  priv->remmina_file,
    1443  "ssh_tunnel_certfile",
    1444  (priv->ssh_tunnel_certfile_chooser ? gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(priv->ssh_tunnel_certfile_chooser)) : NULL));
    1445 
    1447  priv->remmina_file,
    1448  "ssh_tunnel_password",
    1449  (ssh_tunnel_enabled && (ssh_tunnel_auth == SSH_AUTH_PASSWORD)) ? gtk_entry_get_text(GTK_ENTRY(priv->ssh_tunnel_auth_password)) : NULL);
    1450 
    1452  priv->remmina_file,
    1453  "ssh_tunnel_passphrase",
    1454  (ssh_tunnel_enabled && (ssh_tunnel_auth == SSH_AUTH_PUBLICKEY || ssh_tunnel_auth == SSH_AUTH_AUTO_PUBLICKEY)) ? gtk_entry_get_text(GTK_ENTRY(priv->ssh_tunnel_passphrase)) : NULL);
    1455 }
    1456 
    1458  gchar * setting_name_to_validate,
    1459  gconstpointer value,
    1460  GError ** err)
    1461 {
    1462  if (!setting_name_to_validate || !value || !gfe) {
    1463  if (!setting_name_to_validate) {
    1464  g_critical(_("(%s: %i): Can't validate setting '%s' since 'value' or 'gfe' "
    1465  "are NULL!"),
    1466  __func__, __LINE__, setting_name_to_validate);
    1467  } else {
    1468  g_critical(_("(%s: %i): Can't validate user input since "
    1469  "'setting_name_to_validate', 'value' or 'gfe' are NULL!"),
    1470  __func__, __LINE__);
    1471  }
    1472  g_set_error(err, 1, 1, _("Internal error."));
    1473  return FALSE;
    1474  }
    1475 
    1476  if (strcmp(setting_name_to_validate, "notes_text") == 0) {
    1477  // Not a plugin setting. Bail out early.
    1478  return TRUE;
    1479  }
    1480 
    1481  const RemminaProtocolSetting *setting_iter;
    1482  RemminaProtocolPlugin *protocol_plugin;
    1483  RemminaFileEditorPriv *priv = gfe->priv;
    1484  protocol_plugin = priv->plugin;
    1485 
    1486  setting_iter = protocol_plugin->basic_settings;
    1487  if (setting_iter) {
    1488  // gboolean found = FALSE;
    1489  while (setting_iter->type != REMMINA_PROTOCOL_SETTING_TYPE_END) {
    1490  if (setting_iter->name == NULL) {
    1491  g_error("Internal error: a setting name in protocol plugin %s is "
    1492  "null. Please fix RemminaProtocolSetting struct content.",
    1493  protocol_plugin->name);
    1494  } else if ((gchar *)setting_name_to_validate) {
    1495  if (strcmp((gchar *)setting_name_to_validate, setting_iter->name) == 0) {
    1496  // found = TRUE;
    1497 
    1498  gpointer validator_data = setting_iter->validator_data;
    1499  GCallback validator = setting_iter->validator;
    1500 
    1501  // Default behaviour is that everything is valid,
    1502  // except a validator is given and its returned GError is not NULL.
    1503  GError *err_ret = NULL;
    1504 
    1505  g_debug("Checking setting '%s' for validation.", setting_iter->name);
    1506  if (validator != NULL) {
    1507  // Looks weird but it calls the setting's validator
    1508  // function using setting_name_to_validate, value and
    1509  // validator_data as parameters and it returns a GError*.
    1510  err_ret = ((GError * (*)(gpointer, gconstpointer, gpointer)) validator)(setting_name_to_validate, value, validator_data);
    1511  }
    1512 
    1513  if (err_ret) {
    1514  g_debug("it has a validator function and it had an error!");
    1515  // pass err (returned value) to function caller.
    1516  *err = err_ret;
    1517  return FALSE;
    1518  }
    1519 
    1520  break;
    1521  }
    1522  }
    1523  setting_iter++;
    1524  }
    1525 
    1526  // if (!found) {
    1527  // TOO VERBOSE:
    1528  // g_warning("%s is not a plugin setting!", setting_name_to_validate);
    1529  // }
    1530  }
    1531 
    1532  return TRUE;
    1533 }
    1534 
    1536  GtkWidget ** failed_widget)
    1537 {
    1538  TRACE_CALL(__func__);
    1539  RemminaFileEditorPriv *priv = gfe->priv;
    1540  GHashTableIter iter;
    1541  gpointer key;
    1542  gpointer widget;
    1543  GtkTextBuffer *buffer;
    1544  gchar *escaped, *unescaped;
    1545  GtkTextIter start, end;
    1546 
    1547  GError *err = NULL;
    1548  *failed_widget = NULL;
    1549 
    1550  g_hash_table_iter_init(&iter, priv->setting_widgets);
    1551  while (g_hash_table_iter_next(&iter, &key, &widget)) {
    1552  // We don't want to save or validate grayed-out settings.
    1553  if (!gtk_widget_get_sensitive(GTK_WIDGET(widget))) {
    1554  g_debug("Grayed-out setting-widget '%s' will not be saved.",
    1555  gtk_widget_get_name(widget));
    1556  continue;
    1557  }
    1558 
    1559  if (GTK_IS_ENTRY(widget)) {
    1560  const gchar *value = gtk_entry_get_text(GTK_ENTRY(widget));
    1561 
    1562  if (!remmina_file_editor_validate_settings(gfe, (gchar *)key, value, &err)) {
    1563  // Error while validating!
    1564  // err should be set now.
    1565  *failed_widget = widget;
    1566  break;
    1567  }
    1568 
    1569  remmina_file_set_string(priv->remmina_file, (gchar *)key, value);
    1570  } else if (GTK_IS_TEXT_VIEW(widget)) {
    1571  buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
    1572  gtk_text_buffer_get_start_iter(buffer, &start);
    1573  gtk_text_buffer_get_end_iter(buffer, &end);
    1574  unescaped = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
    1575  escaped = g_uri_escape_string(unescaped, NULL, TRUE);
    1576 
    1577  if (!remmina_file_editor_validate_settings(gfe, (gchar *)key, escaped, &err)) {
    1578  // Error while validating!
    1579  // err should be set now.
    1580  *failed_widget = widget;
    1581  break;
    1582  }
    1583 
    1584  remmina_file_set_string(priv->remmina_file, (gchar *)key, escaped);
    1585  g_free(escaped);
    1586  } else if (GTK_IS_COMBO_BOX(widget)) {
    1587  gchar *value = remmina_public_combo_get_active_text(GTK_COMBO_BOX(widget));
    1588 
    1589  if (!remmina_file_editor_validate_settings(gfe, (gchar *)key, value, &err)) {
    1590  // Error while validating!
    1591  // err should be set now.
    1592  *failed_widget = widget;
    1593  break;
    1594  }
    1595 
    1596  remmina_file_set_string(priv->remmina_file, (gchar *)key, value);
    1597  } else if (GTK_IS_FILE_CHOOSER(widget)) {
    1598  gchar *value = gtk_widget_get_sensitive(GTK_WIDGET(widget)) ? gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget)) : NULL;
    1599 
    1600  if (!remmina_file_editor_validate_settings(gfe, (gchar *)key, value, &err)) {
    1601  // Error while validating!
    1602  // err should be set now.
    1603  g_free(value);
    1604  *failed_widget = widget;
    1605  break;
    1606  }
    1607 
    1608  remmina_file_set_string(priv->remmina_file, (gchar *)key, value);
    1609  g_free(value);
    1610  } else if (GTK_IS_TOGGLE_BUTTON(widget)) {
    1611  gboolean value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
    1612 
    1613  if (!remmina_file_editor_validate_settings(gfe, (gchar *)key, &value, &err)) {
    1614  // Error while validating!
    1615  // err should be set now.
    1616  *failed_widget = widget;
    1617  break;
    1618  }
    1619 
    1620  remmina_file_set_int(priv->remmina_file, (gchar *)key, value);
    1621  }
    1622  }
    1623 
    1624  if (err) {
    1625  return err;
    1626  }
    1627 
    1628  return NULL;
    1629 }
    1630 
    1632  GtkWidget ** failed_widget)
    1633 {
    1634  TRACE_CALL(__func__);
    1635  int res_w, res_h;
    1636  gchar *custom_resolution;
    1638 
    1639  RemminaFileEditorPriv *priv = gfe->priv;
    1640 
    1641  remmina_file_set_string(priv->remmina_file, "name", gtk_entry_get_text(GTK_ENTRY(priv->name_entry)));
    1642 
    1643  remmina_file_set_string(priv->remmina_file, "labels", gtk_entry_get_text(GTK_ENTRY(priv->labels_entry)));
    1644 
    1645  remmina_file_set_string(priv->remmina_file, "group",
    1646  (priv->group_combo ? remmina_public_combo_get_active_text(GTK_COMBO_BOX(priv->group_combo)) : NULL));
    1647 
    1648  remmina_file_set_string(priv->remmina_file, "protocol",
    1649  remmina_public_combo_get_active_text(GTK_COMBO_BOX(priv->protocol_combo)));
    1650 
    1651  remmina_file_set_string(priv->remmina_file, "server",
    1652  (priv->server_combo ? remmina_public_combo_get_active_text(GTK_COMBO_BOX(priv->server_combo)) : NULL));
    1653 
    1654  if (priv->resolution_auto_radio) {
    1655  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->resolution_auto_radio))) {
    1656  /* Resolution is set to auto (which means: Use client fullscreen resolution, aka use client resolution) */
    1657  res_w = res_h = 0;
    1658  res_mode = RES_USE_CLIENT;
    1659  } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->resolution_iws_radio))) {
    1660  /* Resolution is set to initial window size */
    1661  res_w = res_h = 0;
    1662  res_mode = RES_USE_INITIAL_WINDOW_SIZE;
    1663  } else {
    1664  /* Resolution is set to a value from the list */
    1665  custom_resolution = remmina_public_combo_get_active_text(GTK_COMBO_BOX(priv->resolution_custom_combo));
    1666  if (remmina_public_split_resolution_string(custom_resolution, &res_w, &res_h))
    1667  res_mode = RES_USE_CUSTOM;
    1668  else
    1669  res_mode = RES_USE_INITIAL_WINDOW_SIZE;
    1670  g_free(custom_resolution);
    1671  }
    1672  remmina_file_set_int(priv->remmina_file, "resolution_mode", res_mode);
    1673  remmina_file_set_int(priv->remmina_file, "resolution_width", res_w);
    1674  remmina_file_set_int(priv->remmina_file, "resolution_height", res_h);
    1675  }
    1676 
    1677  if (priv->keymap_combo)
    1678  remmina_file_set_string(priv->remmina_file, "keymap",
    1679  remmina_public_combo_get_active_text(GTK_COMBO_BOX(priv->keymap_combo)));
    1680 
    1683  return remmina_file_editor_update_settings(gfe, failed_widget);
    1684 }
    1685 
    1686 static void remmina_file_editor_on_default(GtkWidget *button, RemminaFileEditor *gfe)
    1687 {
    1688  TRACE_CALL(__func__);
    1689  RemminaFile *gf;
    1690  GtkWidget *dialog;
    1691 
    1692  GtkWidget *failed_widget = NULL;
    1693  GError *err = remmina_file_editor_update(gfe, &failed_widget);
    1694  if (err) {
    1695  g_warning(_("Couldn't validate user input. %s"), err->message);
    1696  remmina_file_editor_show_validation_error_popup(gfe, failed_widget, err);
    1697  return;
    1698  }
    1699 
    1700  gf = remmina_file_dup(gfe->priv->remmina_file);
    1701 
    1703 
    1704  /* Clear properties that should never be default */
    1705  remmina_file_set_string(gf, "name", NULL);
    1706  remmina_file_set_string(gf, "server", NULL);
    1707  remmina_file_set_string(gf, "password", NULL);
    1708  remmina_file_set_string(gf, "precommand", NULL);
    1709  remmina_file_set_string(gf, "postcommand", NULL);
    1710 
    1711  remmina_file_set_string(gf, "ssh_tunnel_server", NULL);
    1712  remmina_file_set_string(gf, "ssh_tunnel_password", NULL);
    1713  remmina_file_set_string(gf, "ssh_tunnel_passphrase", NULL);
    1714 
    1715  remmina_file_save(gf);
    1716  remmina_file_free(gf);
    1717 
    1718  dialog = gtk_message_dialog_new(GTK_WINDOW(gfe), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO,
    1719  GTK_BUTTONS_OK, _("Default settings saved."));
    1720  gtk_dialog_run(GTK_DIALOG(dialog));
    1721  gtk_widget_destroy(dialog);
    1722 }
    1723 
    1724 static void remmina_file_editor_on_save(GtkWidget *button, RemminaFileEditor *gfe)
    1725 {
    1726  TRACE_CALL(__func__);
    1727 
    1728  GtkWidget *failed_widget = NULL;
    1729  GError *err = remmina_file_editor_update(gfe, &failed_widget);
    1730  if (err) {
    1731  g_warning(_("Couldn't validate user input. %s"), err->message);
    1732  remmina_file_editor_show_validation_error_popup(gfe, failed_widget, err);
    1733  return;
    1734  }
    1735 
    1737 
    1738  remmina_file_save(gfe->priv->remmina_file);
    1740 
    1741  gtk_widget_destroy(GTK_WIDGET(gfe));
    1742 }
    1743 
    1744 static void remmina_file_editor_on_connect(GtkWidget *button, RemminaFileEditor *gfe)
    1745 {
    1746  TRACE_CALL(__func__);
    1747  RemminaFile *gf;
    1748 
    1749  GtkWidget *failed_widget = NULL;
    1750  GError *err = remmina_file_editor_update(gfe, &failed_widget);
    1751  if (err) {
    1752  g_warning(_("Couldn't validate user input. %s"), err->message);
    1753  remmina_file_editor_show_validation_error_popup(gfe, failed_widget, err);
    1754  return;
    1755  }
    1756 
    1757  gf = remmina_file_dup(gfe->priv->remmina_file);
    1758  /* Put server into name for "Quick Connect" */
    1759  if (remmina_file_get_filename(gf) == NULL)
    1760  remmina_file_set_string(gf, "name", remmina_file_get_string(gf, "server"));
    1761  gtk_widget_destroy(GTK_WIDGET(gfe));
    1762  gf->prevent_saving = TRUE;
    1763  rcw_open_from_file(gf);
    1764 }
    1765 
    1766 static void remmina_file_editor_on_save_connect(GtkWidget *button, RemminaFileEditor *gfe)
    1767 {
    1768  TRACE_CALL(__func__);
    1770  RemminaFile *gf;
    1771 
    1772  GtkWidget *failed_widget = NULL;
    1773  GError *err = remmina_file_editor_update(gfe, &failed_widget);
    1774  if (err) {
    1775  g_warning(_("Couldn't validate user input. %s"), err->message);
    1776  remmina_file_editor_show_validation_error_popup(gfe, failed_widget, err);
    1777  return;
    1778  }
    1779 
    1781 
    1782  remmina_file_save(gfe->priv->remmina_file);
    1784 
    1785  gf = remmina_file_dup(gfe->priv->remmina_file);
    1786  /* Put server into name for Quick Connect */
    1787  if (remmina_file_get_filename(gf) == NULL)
    1788  remmina_file_set_string(gf, "name", remmina_file_get_string(gf, "server"));
    1789  gtk_widget_destroy(GTK_WIDGET(gfe));
    1790  rcw_open_from_file(gf);
    1791 }
    1792 
    1793 static void remmina_file_editor_on_cancel(GtkWidget *button, RemminaFileEditor *gfe)
    1794 {
    1795  TRACE_CALL(__func__);
    1796  gtk_widget_destroy(GTK_WIDGET(gfe));
    1797 }
    1798 
    1800 {
    1801  TRACE_CALL(__func__);
    1802  RemminaFileEditorPriv *priv;
    1803  GtkWidget *widget;
    1804 
    1805  priv = g_new0(RemminaFileEditorPriv, 1);
    1806  gfe->priv = priv;
    1807 
    1808  /* Create the editor dialog */
    1809  gtk_window_set_title(GTK_WINDOW(gfe), _("Remote Connection Profile"));
    1810 
    1811  widget = gtk_dialog_add_button(GTK_DIALOG(gfe), (_("_Cancel")), GTK_RESPONSE_CANCEL);
    1812  g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_file_editor_on_cancel), gfe);
    1813 
    1814  /* Default button */
    1815  widget = gtk_dialog_add_button(GTK_DIALOG(gfe), (_("Save as Default")), GTK_RESPONSE_OK);
    1816  gtk_widget_set_tooltip_text(GTK_WIDGET(widget), _("Use the current settings as the default for all new connection profiles"));
    1817  g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_file_editor_on_default), gfe);
    1818 
    1819  widget = gtk_dialog_add_button(GTK_DIALOG(gfe), (_("_Save")), GTK_RESPONSE_APPLY);
    1820  g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_file_editor_on_save), gfe);
    1821  gtk_widget_set_sensitive(widget, FALSE);
    1822  priv->save_button = widget;
    1823 
    1824  widget = gtk_dialog_add_button(GTK_DIALOG(gfe), (_("Connect")), GTK_RESPONSE_ACCEPT);
    1825  g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_file_editor_on_connect), gfe);
    1826 
    1827  widget = gtk_dialog_add_button(GTK_DIALOG(gfe), (_("_Save and Connect")), GTK_RESPONSE_OK);
    1828  gtk_widget_set_can_default(widget, TRUE);
    1829  g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_file_editor_on_save_connect), gfe);
    1830 
    1831  gtk_dialog_set_default_response(GTK_DIALOG(gfe), GTK_RESPONSE_OK);
    1832  gtk_window_set_default_size(GTK_WINDOW(gfe), 800, 600);
    1833 
    1834  g_signal_connect(G_OBJECT(gfe), "destroy", G_CALLBACK(remmina_file_editor_destroy), NULL);
    1835  g_signal_connect(G_OBJECT(gfe), "realize", G_CALLBACK(remmina_file_editor_on_realize), NULL);
    1836 
    1837  priv->setting_widgets = g_hash_table_new(g_str_hash, g_str_equal);
    1838 
    1839  remmina_widget_pool_register(GTK_WIDGET(gfe));
    1840 }
    1841 
    1842 static gboolean remmina_file_editor_iterate_protocol(gchar *protocol, RemminaPlugin *plugin, gpointer data)
    1843 {
    1844  TRACE_CALL(__func__);
    1845  RemminaFileEditor *gfe = REMMINA_FILE_EDITOR(data);
    1846  GtkListStore *store;
    1847  GtkTreeIter iter;
    1848  gboolean first;
    1849 
    1850  store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(gfe->priv->protocol_combo)));
    1851 
    1852  first = !gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
    1853 
    1854  gtk_list_store_append(store, &iter);
    1855  gtk_list_store_set(store, &iter, 0, protocol, 1, g_dgettext(plugin->domain, plugin->description), 2,
    1856  ((RemminaProtocolPlugin *)plugin)->icon_name, -1);
    1857 
    1858  if (first || g_strcmp0(protocol, remmina_file_get_string(gfe->priv->remmina_file, "protocol")) == 0)
    1859  gtk_combo_box_set_active_iter(GTK_COMBO_BOX(gfe->priv->protocol_combo), &iter);
    1860 
    1861  return FALSE;
    1862 }
    1863 
    1865 {
    1866  TRACE_CALL(__func__);
    1867  RemminaFileEditorPriv *priv;
    1868 
    1869  priv = gfe->priv;
    1870  gtk_widget_set_sensitive(priv->group_combo, TRUE);
    1871  gtk_widget_set_sensitive(priv->save_button, TRUE);
    1872 }
    1873 
    1874 static void remmina_file_editor_entry_on_changed(GtkEditable *editable, RemminaFileEditor *gfe)
    1875 {
    1876  TRACE_CALL(__func__);
    1877  RemminaFileEditorPriv *priv;
    1878 
    1879  priv = gfe->priv;
    1880  if (remmina_file_get_filename(priv->remmina_file) == NULL) {
    1881  remmina_file_generate_filename(priv->remmina_file);
    1882  /* TODO: Probably to be removed */
    1884  } else {
    1885  remmina_file_delete(remmina_file_get_filename(priv->remmina_file));
    1886  remmina_file_generate_filename(priv->remmina_file);
    1888  }
    1889 }
    1890 
    1892 {
    1893  TRACE_CALL(__func__);
    1894  RemminaFileEditorPriv *priv;
    1895 
    1896  priv = gfe->priv;
    1897  if (remmina_file_get_filename(priv->remmina_file) == NULL) {
    1898  remmina_file_generate_filename(priv->remmina_file);
    1899  } else {
    1900  remmina_file_delete(remmina_file_get_filename(priv->remmina_file));
    1901  remmina_file_generate_filename(priv->remmina_file);
    1902  }
    1903 }
    1904 
    1906 {
    1907  TRACE_CALL(__func__);
    1908  RemminaFileEditor *gfe;
    1909  RemminaFileEditorPriv *priv;
    1910  GtkWidget *grid;
    1911  GtkWidget *widget;
    1912  gchar *groups;
    1913  gchar *s;
    1914  const gchar *cs;
    1915 
    1916  gfe = REMMINA_FILE_EDITOR(g_object_new(REMMINA_TYPE_FILE_EDITOR, NULL));
    1917  priv = gfe->priv;
    1918  priv->remmina_file = remminafile;
    1919 
    1920  if (remmina_file_get_filename(remminafile) == NULL)
    1921  gtk_dialog_set_response_sensitive(GTK_DIALOG(gfe), GTK_RESPONSE_APPLY, FALSE);
    1922 
    1923  /* Create the "Profile" group on the top (for name and protocol) */
    1924  grid = gtk_grid_new();
    1925  gtk_widget_show(grid);
    1926  gtk_grid_set_row_spacing(GTK_GRID(grid), 4);
    1927  gtk_grid_set_column_spacing(GTK_GRID(grid), 8);
    1928  gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE);
    1929  gtk_container_set_border_width(GTK_CONTAINER(grid), 8);
    1930  gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(gfe))), grid, FALSE, FALSE, 2);
    1931 
    1932  // remmina_public_create_group(GTK_GRID(grid), _("Profile"), 0, 4, 3);
    1933 
    1934  gboolean profile_file_exists = (remmina_file_get_filename(remminafile) != NULL);
    1935 
    1936  /* Profile: Name */
    1937  widget = gtk_label_new(_("Name"));
    1938  gtk_widget_show(widget);
    1939  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    1940  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    1941  gtk_grid_attach(GTK_GRID(grid), widget, 0, 3, 2, 1);
    1942  gtk_grid_set_column_spacing(GTK_GRID(grid), 10);
    1943 
    1944  widget = gtk_entry_new();
    1945  gtk_widget_show(widget);
    1946  gtk_grid_attach(GTK_GRID(grid), widget, 1, 3, 3, 1);
    1947  gtk_entry_set_max_length(GTK_ENTRY(widget), 100);
    1948  priv->name_entry = widget;
    1949 
    1950  if (!profile_file_exists) {
    1951  gtk_entry_set_text(GTK_ENTRY(widget), _("Quick Connect"));
    1952 #if GTK_CHECK_VERSION(3, 16, 0)
    1953  gtk_entry_grab_focus_without_selecting(GTK_ENTRY(widget));
    1954 #endif
    1955  g_signal_connect(G_OBJECT(widget), "changed", G_CALLBACK(remmina_file_editor_entry_on_changed), gfe);
    1956  } else {
    1957  cs = remmina_file_get_string(remminafile, "name");
    1958  gtk_entry_set_text(GTK_ENTRY(widget), cs ? cs : "");
    1959  }
    1960 
    1961  /* Profile: Group */
    1962  widget = gtk_label_new(_("Group"));
    1963  gtk_widget_show(widget);
    1964  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    1965  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    1966  gtk_grid_attach(GTK_GRID(grid), widget, 0, 6, 2, 1);
    1967 
    1969  priv->group_combo = remmina_public_create_combo_entry(groups, remmina_file_get_string(remminafile, "group"), FALSE);
    1970  g_free(groups);
    1971  gtk_widget_show(priv->group_combo);
    1972  gtk_grid_attach(GTK_GRID(grid), priv->group_combo, 1, 6, 3, 1);
    1973  gtk_widget_set_sensitive(priv->group_combo, FALSE);
    1974 
    1975  s = g_strdup_printf(_("Use '%s' as subgroup delimiter"), "/");
    1976  gtk_widget_set_tooltip_text(priv->group_combo, s);
    1977  g_free(s);
    1978 
    1979  /* Profile: Labels */
    1980  widget = gtk_label_new(_("Labels"));
    1981  gtk_widget_show(widget);
    1982  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    1983  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    1984  gtk_grid_attach(GTK_GRID(grid), widget, 0, 9, 2, 1);
    1985  gtk_grid_set_column_spacing(GTK_GRID(grid), 10);
    1986 
    1987  widget = gtk_entry_new();
    1988  gtk_widget_show(widget);
    1989  gtk_grid_attach(GTK_GRID(grid), widget, 1, 9, 3, 1);
    1990  gtk_entry_set_max_length(GTK_ENTRY(widget), 255);
    1991  priv->labels_entry = widget;
    1992 
    1993  if (!profile_file_exists) {
    1994  gtk_widget_set_tooltip_text(widget, _("Label1,Label2"));
    1995 #if GTK_CHECK_VERSION(3, 16, 0)
    1996  gtk_entry_grab_focus_without_selecting(GTK_ENTRY(widget));
    1997 #endif
    1998  g_signal_connect(G_OBJECT(widget), "changed", G_CALLBACK(remmina_file_editor_entry_on_changed), gfe);
    1999  } else {
    2000  cs = remmina_file_get_string(remminafile, "labels");
    2001  gtk_entry_set_text(GTK_ENTRY(widget), cs ? cs : "");
    2002  }
    2003 
    2004  /* Profile: Protocol */
    2005  widget = gtk_label_new(_("Protocol"));
    2006  gtk_widget_show(widget);
    2007  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    2008  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    2009  gtk_grid_attach(GTK_GRID(grid), widget, 0, 12, 2, 1);
    2010 
    2011  widget = remmina_public_create_combo(TRUE);
    2012  gtk_widget_show(widget);
    2013  gtk_grid_attach(GTK_GRID(grid), widget, 1, 12, 3, 1);
    2014  priv->protocol_combo = widget;
    2016  g_signal_connect(G_OBJECT(widget), "changed", G_CALLBACK(remmina_file_editor_protocol_combo_on_changed), gfe);
    2017 
    2018  /* Create the "Preference" frame */
    2019  widget = gtk_event_box_new();
    2020  gtk_widget_show(widget);
    2021  gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(gfe))), widget, TRUE, TRUE, 2);
    2022  priv->config_box = widget;
    2023 
    2024  priv->config_container = NULL;
    2025  priv->config_scrollable = NULL;
    2026 
    2027  remmina_file_editor_protocol_combo_on_changed(GTK_COMBO_BOX(priv->protocol_combo), gfe);
    2028 
    2030 
    2031  return GTK_WIDGET(gfe);
    2032 }
    2033 
    2034 GtkWidget *remmina_file_editor_new(void)
    2035 {
    2036  TRACE_CALL(__func__);
    2037  return remmina_file_editor_new_full(NULL, NULL);
    2038 }
    2039 
    2040 GtkWidget *remmina_file_editor_new_full(const gchar *server, const gchar *protocol)
    2041 {
    2042  TRACE_CALL(__func__);
    2043  RemminaFile *remminafile;
    2044 
    2045  remminafile = remmina_file_new();
    2046  if (server)
    2047  remmina_file_set_string(remminafile, "server", server);
    2048  if (protocol)
    2049  remmina_file_set_string(remminafile, "protocol", protocol);
    2050 
    2051  return remmina_file_editor_new_from_file(remminafile);
    2052 }
    2053 
    2054 GtkWidget *remmina_file_editor_new_copy(const gchar *filename)
    2055 {
    2056  TRACE_CALL(__func__);
    2057  RemminaFile *remminafile;
    2058  GtkWidget *dialog;
    2059 
    2060  remminafile = remmina_file_copy(filename);
    2061 
    2062  if (remminafile) {
    2063  return remmina_file_editor_new_from_file(remminafile);
    2064  } else {
    2065  dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
    2066  _("Could not find the file “%s”."), filename);
    2067  gtk_dialog_run(GTK_DIALOG(dialog));
    2068  gtk_widget_destroy(dialog);
    2069  return NULL;
    2070  }
    2071 }
    2072 
    2073 GtkWidget *remmina_file_editor_new_from_filename(const gchar *filename)
    2074 {
    2075  TRACE_CALL(__func__);
    2076  RemminaFile *remminafile;
    2077 
    2078  remminafile = remmina_file_manager_load_file(filename);
    2079  if (remminafile) {
    2080  if (remmina_file_get_int(remminafile, "profile-lock", FALSE) && remmina_unlock_new(remmina_main_get_window()) == 0)
    2081  return NULL;
    2082  return remmina_file_editor_new_from_file(remminafile);
    2083  } else {
    2084  GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
    2085  _("Could not find the file “%s”."), filename);
    2086  gtk_dialog_run(GTK_DIALOG(dialog));
    2087  gtk_widget_destroy(dialog);
    2088  return NULL;
    2089  }
    2090 }
    +Go to the documentation of this file.
    1 /*
    2  * Remmina - The GTK+ Remote Desktop Client
    3  * Copyright (C) 2009-2011 Vic Lee
    4  * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
    5  * Copyright (C) 2016-2023 Antenore Gatta, Giovanni Panozzo
    6  *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    15  * GNU General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
    20  * Boston, MA 02110-1301, USA.
    21  *
    22  * In addition, as a special exception, the copyright holders give
    23  * permission to link the code of portions of this program with the
    24  * OpenSSL library under certain conditions as described in each
    25  * individual source file, and distribute linked combinations
    26  * including the two.
    27  * You must obey the GNU General Public License in all respects
    28  * for all of the code used other than OpenSSL. * If you modify
    29  * file(s) with this exception, you may extend this exception to your
    30  * version of the file(s), but you are not obligated to do so. * If you
    31  * do not wish to do so, delete this exception statement from your
    32  * version. * If you delete this exception statement from all source
    33  * files in the program, then also delete it here.
    34  *
    35  */
    36 
    37 #include <ctype.h>
    38 #include "config.h"
    39 #ifdef HAVE_LIBAVAHI_UI
    40 #include <avahi-ui/avahi-ui.h>
    41 #endif
    42 #include "remmina_public.h"
    43 #include "remmina_pref.h"
    44 #include "rcw.h"
    46 #include "remmina_file.h"
    47 #include "remmina_file_editor.h"
    48 #include "remmina_file_manager.h"
    49 #include "remmina_icon.h"
    50 #include "remmina_main.h"
    51 #include "remmina_plugin_manager.h"
    52 #include "remmina_pref_dialog.h"
    53 #include "remmina_ssh.h"
    54 #include "remmina_string_list.h"
    55 #include "remmina_unlock.h"
    56 #include "remmina_widget_pool.h"
    57 
    58 G_DEFINE_TYPE(RemminaFileEditor, remmina_file_editor, GTK_TYPE_DIALOG)
    59 
    60 static const gchar *server_tips = N_("<big>"
    61  "Supported formats\n"
    62  "• server\n"
    63  "• server[:port]\n"
    64  "VNC additional formats\n"
    65  "• ID:repeater ID number\n"
    66  "• unix:///path/socket.sock"
    67  "</big>");
    68 
    69 static const gchar *cmd_tips = N_("<big>"
    70  "• command in PATH args %h\n"
    71  "• /path/to/foo -options %h %u\n"
    72  "• %h is substituted with the server name\n"
    73  "• %t is substituted with the SSH server name\n"
    74  "• %u is substituted with the username\n"
    75  "• %U is substituted with the SSH username\n"
    76  "• %p is substituted with Remmina profile name\n"
    77  "• %g is substituted with Remmina profile group name\n"
    78  "• %d is substituted with local date and time in ISO 8601 format\n"
    79  "Do not run in background if you want the command to be executed before connecting.\n"
    80  "</big>");
    81 
    82 #ifdef HAVE_LIBSSH
    83 static const gchar *server_tips2 = N_("<big>"
    84  "Supported formats\n"
    85  "• server\n"
    86  "• server[:port]\n"
    87  "• username@server[:port] (SSH protocol only)"
    88  "</big>");
    89 #endif
    90 
    91 struct _RemminaFileEditorPriv {
    92  RemminaFile * remmina_file;
    93  RemminaProtocolPlugin * plugin;
    94  const gchar * avahi_service_type;
    95 
    96  GtkWidget * name_entry;
    97  GtkWidget * labels_entry;
    98  GtkWidget * group_combo;
    99  GtkWidget * protocol_combo;
    100  GtkWidget * save_button;
    101 
    102  GtkWidget * config_box;
    103  GtkWidget * config_scrollable;
    104  GtkWidget * config_viewport;
    105  GtkWidget * config_container;
    106 
    107  GtkWidget * server_combo;
    108  GtkWidget * resolution_iws_radio;
    109  GtkWidget * resolution_auto_radio;
    110  GtkWidget * resolution_custom_radio;
    111  GtkWidget * resolution_custom_combo;
    112  GtkWidget * keymap_combo;
    113 
    114  GtkWidget * behavior_autostart_check;
    115  GtkWidget * behavior_precommand_entry;
    116  GtkWidget * behavior_postcommand_entry;
    117  GtkWidget * behavior_lock_check;
    118 
    119  GtkWidget * ssh_tunnel_enabled_check;
    120  GtkWidget * ssh_tunnel_loopback_check;
    121  GtkWidget * ssh_tunnel_server_default_radio;
    122  GtkWidget * ssh_tunnel_server_custom_radio;
    123  GtkWidget * ssh_tunnel_server_entry;
    124  GtkWidget * ssh_tunnel_auth_agent_radio;
    125  GtkWidget * ssh_tunnel_auth_password_radio;
    126  GtkWidget * ssh_tunnel_auth_password;
    127  GtkWidget * ssh_tunnel_passphrase;
    128  GtkWidget * ssh_tunnel_auth_publickey_radio;
    129  GtkWidget * ssh_tunnel_auth_auto_publickey_radio;
    130  GtkWidget * ssh_tunnel_auth_combo;
    131  GtkWidget * ssh_tunnel_username_entry;
    132  GtkWidget * ssh_tunnel_privatekey_chooser;
    133  GtkWidget * ssh_tunnel_certfile_chooser;
    134 
    135  GHashTable * setting_widgets;
    136 };
    137 
    139 {
    140  TRACE_CALL(__func__);
    141 }
    142 
    159  GtkWidget * failed_widget,
    160  GError * err)
    161 {
    162  if (!err) {
    163  err = NULL; // g_set_error doesn't like overwriting errors.
    164  g_set_error(&err, 1, 1, _("Input is invalid."));
    165  }
    166 
    167  if (!gfe || !failed_widget) {
    168  g_critical("(%s): Parameters RemminaFileEditor 'gfe' or "
    169  "GtkWidget* 'failed_widget' are 'NULL'!",
    170  __func__);
    171  return;
    172  }
    173 
    174  gint widget_width = gtk_widget_get_allocated_width(failed_widget);
    175  gint widget_height = gtk_widget_get_allocated_height(failed_widget);
    176 
    177  GtkWidget *err_label = gtk_label_new("");
    178  GtkWidget *alert_icon = NULL;
    179  GtkWindow *err_window = GTK_WINDOW(gtk_window_new(GTK_WINDOW_TOPLEVEL));
    180  GtkWidget *box = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    181  GdkWindow *window = gtk_widget_get_window(failed_widget);
    182 
    183  GtkAllocation allocation;
    184  gint failed_widget_x, failed_widget_y;
    185 
    186  gchar *markup = g_strdup_printf("<span size='large'>%s</span>", err->message);
    187 
    188  // Setup err_window
    189  gtk_window_set_decorated(err_window, FALSE);
    190  gtk_window_set_type_hint(err_window, GDK_WINDOW_TYPE_HINT_TOOLTIP);
    191  gtk_window_set_default_size(err_window, widget_width, widget_height);
    192  gtk_window_set_title(err_window, "Error");
    193  gtk_window_set_resizable(err_window, TRUE);
    194 
    195  // Move err_window under failed_widget
    196  gtk_window_set_attached_to(err_window, failed_widget);
    197  gtk_window_set_transient_for(err_window, GTK_WINDOW(gfe));
    198  gdk_window_get_origin(GDK_WINDOW(window), &failed_widget_x, &failed_widget_y);
    199  gtk_widget_get_allocation(failed_widget, &allocation);
    200  failed_widget_x += allocation.x;
    201  failed_widget_y += allocation.y + allocation.height;
    202  gtk_window_move(err_window, failed_widget_x, failed_widget_y);
    203 
    204  // Setup label
    205  gtk_label_set_selectable(GTK_LABEL(err_label), FALSE);
    206  gtk_label_set_max_width_chars(GTK_LABEL(err_label), 1);
    207  gtk_widget_set_hexpand(GTK_WIDGET(err_label), TRUE);
    208  gtk_widget_set_vexpand(GTK_WIDGET(err_label), TRUE);
    209  gtk_label_set_ellipsize(GTK_LABEL(err_label), PANGO_ELLIPSIZE_END);
    210  gtk_label_set_line_wrap(GTK_LABEL(err_label), TRUE);
    211  gtk_label_set_line_wrap_mode(GTK_LABEL(err_label), PANGO_WRAP_WORD_CHAR);
    212  gtk_label_set_markup(GTK_LABEL(err_label), markup);
    213 
    214  alert_icon = gtk_image_new_from_icon_name("dialog-warning-symbolic",
    215  GTK_ICON_SIZE_DND);
    216 
    217  // Fill icon and label into a box.
    218  gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(alert_icon), FALSE, FALSE, 0);
    219  gtk_box_pack_start(GTK_BOX(box), GTK_WIDGET(err_label), TRUE, TRUE, 5);
    220 
    221  // Attach box to err_window
    222  gtk_container_add(GTK_CONTAINER(err_window), GTK_WIDGET(box));
    223 
    224  // Display everything.
    225  gtk_widget_show_all(GTK_WIDGET(err_window));
    226 
    227  // Mouse click and focus-loss will delete the err_window.
    228  g_signal_connect(G_OBJECT(err_window), "focus-out-event",
    229  G_CALLBACK(gtk_window_close), NULL);
    230  g_signal_connect(G_OBJECT(err_window), "button-press-event",
    231  G_CALLBACK(gtk_window_close), NULL);
    232 }
    233 
    234 #ifdef HAVE_LIBAVAHI_UI
    235 
    236 static void remmina_file_editor_browse_avahi(GtkWidget *button, RemminaFileEditor *gfe)
    237 {
    238  TRACE_CALL(__func__);
    239  GtkWidget *dialog;
    240  gchar *host;
    241 
    242  dialog = aui_service_dialog_new(_("Choose a Remote Desktop Server"),
    243  GTK_WINDOW(gfe),
    244  _("_Cancel"), GTK_RESPONSE_CANCEL,
    245  _("_OK"), GTK_RESPONSE_ACCEPT,
    246  NULL);
    247 
    248  gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(gfe));
    249  aui_service_dialog_set_resolve_service(AUI_SERVICE_DIALOG(dialog), TRUE);
    250  aui_service_dialog_set_resolve_host_name(AUI_SERVICE_DIALOG(dialog), TRUE);
    251  aui_service_dialog_set_browse_service_types(AUI_SERVICE_DIALOG(dialog),
    252  gfe->priv->avahi_service_type, NULL);
    253 
    254  if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
    255  host = g_strdup_printf("[%s]:%i",
    256  aui_service_dialog_get_host_name(AUI_SERVICE_DIALOG(dialog)),
    257  aui_service_dialog_get_port(AUI_SERVICE_DIALOG(dialog)));
    258  } else {
    259  host = NULL;
    260  }
    261  gtk_widget_destroy(dialog);
    262 
    263  if (host) {
    264  gtk_entry_set_text(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(gfe->priv->server_combo))), host);
    265  g_free(host);
    266  }
    267 }
    268 #endif
    269 
    270 static void remmina_file_editor_on_realize(GtkWidget *widget, gpointer user_data)
    271 {
    272  TRACE_CALL(__func__);
    273  RemminaFileEditor *gfe;
    274  GtkWidget *defaultwidget;
    275 
    276  gfe = REMMINA_FILE_EDITOR(widget);
    277 
    278  defaultwidget = gfe->priv->server_combo;
    279 
    280  if (defaultwidget) {
    281  if (GTK_IS_EDITABLE(defaultwidget))
    282  gtk_editable_select_region(GTK_EDITABLE(defaultwidget), 0, -1);
    283  gtk_widget_grab_focus(defaultwidget);
    284  }
    285 }
    286 
    287 static void remmina_file_editor_destroy(GtkWidget *widget, gpointer data)
    288 {
    289  TRACE_CALL(__func__);
    290  remmina_file_free(REMMINA_FILE_EDITOR(widget)->priv->remmina_file);
    291  g_hash_table_destroy(REMMINA_FILE_EDITOR(widget)->priv->setting_widgets);
    292  g_free(REMMINA_FILE_EDITOR(widget)->priv);
    293 }
    294 
    295 static void remmina_file_editor_button_on_toggled(GtkToggleButton *togglebutton, GtkWidget *widget)
    296 {
    297  TRACE_CALL(__func__);
    298  gtk_widget_set_sensitive(widget, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(togglebutton)));
    299 }
    300 
    302 {
    303  TRACE_CALL(__func__);
    304  /* Create the notebook */
    305  gfe->priv->config_container = gtk_notebook_new();
    306  gfe->priv->config_viewport = gtk_viewport_new(NULL, NULL);
    307  gfe->priv->config_scrollable = gtk_scrolled_window_new(NULL, NULL);
    308  gtk_container_set_border_width(GTK_CONTAINER(gfe->priv->config_scrollable), 2);
    309  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(gfe->priv->config_scrollable),
    310  GTK_POLICY_AUTOMATIC, GTK_POLICY_ALWAYS);
    311  gtk_widget_show(gfe->priv->config_scrollable);
    312 
    313  gtk_container_add(GTK_CONTAINER(gfe->priv->config_viewport), gfe->priv->config_container);
    314  gtk_container_set_border_width(GTK_CONTAINER(gfe->priv->config_viewport), 2);
    315  gtk_widget_show(gfe->priv->config_viewport);
    316  gtk_container_add(GTK_CONTAINER(gfe->priv->config_scrollable), gfe->priv->config_viewport);
    317  gtk_container_set_border_width(GTK_CONTAINER(gfe->priv->config_container), 2);
    318  gtk_widget_show(gfe->priv->config_container);
    319 
    320  gtk_container_add(GTK_CONTAINER(gfe->priv->config_box), gfe->priv->config_scrollable);
    321 }
    322 
    324  const gchar *stock_id, const gchar *label, gint rows, gint cols)
    325 {
    326  TRACE_CALL(__func__);
    327  GtkWidget *tablabel;
    328  GtkWidget *tabbody;
    329  GtkWidget *grid;
    330  GtkWidget *widget;
    331 
    332  tablabel = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    333  gtk_widget_show(tablabel);
    334 
    335  widget = gtk_image_new_from_icon_name(stock_id, GTK_ICON_SIZE_BUTTON);
    336  gtk_box_pack_start(GTK_BOX(tablabel), widget, FALSE, FALSE, 0);
    337  gtk_widget_show(widget);
    338 
    339  widget = gtk_label_new(label);
    340  gtk_box_pack_start(GTK_BOX(tablabel), widget, FALSE, FALSE, 0);
    341  gtk_widget_show(widget);
    342 
    343  tabbody = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    344  gtk_widget_show(tabbody);
    345  gtk_notebook_append_page(GTK_NOTEBOOK(gfe->priv->config_container), tabbody, tablabel);
    346 
    347  grid = gtk_grid_new();
    348  gtk_widget_show(grid);
    349  gtk_grid_set_row_spacing(GTK_GRID(grid), 8);
    350  gtk_grid_set_column_spacing(GTK_GRID(grid), 8);
    351  gtk_container_set_border_width(GTK_CONTAINER(grid), 15);
    352  gtk_box_pack_start(GTK_BOX(tabbody), grid, FALSE, FALSE, 0);
    353 
    354  return grid;
    355 }
    356 
    357 #ifdef HAVE_LIBSSH
    358 
    360 {
    361  TRACE_CALL(__func__);
    362  gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_server_entry),
    363  gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gfe->priv->ssh_tunnel_enabled_check)) &&
    364  (gfe->priv->ssh_tunnel_server_custom_radio == NULL ||
    365  gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gfe->priv->ssh_tunnel_server_custom_radio))));
    366 }
    367 
    368 static void remmina_file_editor_ssh_tunnel_enabled_check_on_toggled(GtkToggleButton *togglebutton,
    370 {
    371  TRACE_CALL(__func__);
    372  RemminaFileEditorPriv *priv = gfe->priv;
    373  gboolean enabled = TRUE;
    374  gchar *p;
    375  const gchar *cp;
    376  const gchar *s = NULL;
    377 
    378  if (gfe->priv->ssh_tunnel_enabled_check) {
    379  enabled = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gfe->priv->ssh_tunnel_enabled_check));
    380  if (gfe->priv->ssh_tunnel_loopback_check)
    381  gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_loopback_check), enabled);
    382  if (gfe->priv->ssh_tunnel_server_default_radio)
    383  gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_server_default_radio), enabled);
    384  if (gfe->priv->ssh_tunnel_server_custom_radio)
    385  gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_server_custom_radio), enabled);
    387  p = remmina_public_combo_get_active_text(GTK_COMBO_BOX(priv->protocol_combo));
    388  // if (!(g_strcmp0(p, "SFTP") == 0 || g_strcmp0(p, "SSH") == 0)) {
    389  gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_username_entry), enabled);
    390  gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_auth_password), enabled);
    391  gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_auth_combo), enabled);
    392  gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_privatekey_chooser), enabled);
    393  gtk_widget_set_sensitive(GTK_WIDGET(gfe->priv->ssh_tunnel_certfile_chooser), enabled);
    394  //}
    395  g_free(p);
    396  }
    397  // remmina_file_editor_ssh_tunnel_auth_publickey_radio_on_toggled(NULL, gfe);
    398  s = remmina_file_get_string(gfe->priv->remmina_file, "ssh_tunnel_privatekey");
    399  if (s)
    400  gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(gfe->priv->ssh_tunnel_privatekey_chooser), s);
    401  s = remmina_file_get_string(gfe->priv->remmina_file, "ssh_tunnel_certfile");
    402  if (s)
    403  gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(gfe->priv->ssh_tunnel_certfile_chooser), s);
    404 
    405  if (gfe->priv->ssh_tunnel_username_entry)
    406  if (enabled && gtk_entry_get_text(GTK_ENTRY(gfe->priv->ssh_tunnel_username_entry))[0] == '\0') {
    407  cp = remmina_file_get_string(priv->remmina_file, "ssh_tunnel_username");
    408  gtk_entry_set_text(GTK_ENTRY(gfe->priv->ssh_tunnel_username_entry), cp ? cp : "");
    409  }
    410 
    411  if (gfe->priv->ssh_tunnel_auth_password) {
    412  if (enabled && gtk_entry_get_text(GTK_ENTRY(gfe->priv->ssh_tunnel_auth_password))[0] == '\0') {
    413  cp = remmina_file_get_string(priv->remmina_file, "ssh_tunnel_password");
    414  gtk_entry_set_text(GTK_ENTRY(gfe->priv->ssh_tunnel_auth_password), cp ? cp : "");
    415  }
    416  }
    417  if (gfe->priv->ssh_tunnel_passphrase) {
    418  if (enabled && gtk_entry_get_text(GTK_ENTRY(gfe->priv->ssh_tunnel_passphrase))[0] == '\0') {
    419  cp = remmina_file_get_string(priv->remmina_file, "ssh_tunnel_passphrase");
    420  gtk_entry_set_text(GTK_ENTRY(gfe->priv->ssh_tunnel_passphrase), cp ? cp : "");
    421  }
    422  }
    423 }
    424 
    425 #endif
    426 
    427 static void remmina_file_editor_create_server(RemminaFileEditor *gfe, const RemminaProtocolSetting *setting, GtkWidget *grid,
    428  gint row)
    429 {
    430  TRACE_CALL(__func__);
    431  RemminaProtocolPlugin *plugin = gfe->priv->plugin;
    432  GtkWidget *widget;
    433 #ifdef HAVE_LIBAVAHI_UI
    434  GtkWidget *hbox;
    435 #endif
    436  gchar *s;
    437 
    438  widget = gtk_label_new(_("Server"));
    439  gtk_widget_show(widget);
    440  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    441  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    442  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, row + 1);
    443 
    444  s = remmina_pref_get_recent(plugin->name);
    445  widget = remmina_public_create_combo_entry(s, remmina_file_get_string(gfe->priv->remmina_file, "server"), TRUE);
    446  gtk_widget_set_hexpand(widget, TRUE);
    447  gtk_widget_show(widget);
    448  gtk_widget_set_tooltip_markup(widget, _(server_tips));
    449  gtk_entry_set_activates_default(GTK_ENTRY(gtk_bin_get_child(GTK_BIN(widget))), TRUE);
    450  gfe->priv->server_combo = widget;
    451  g_free(s);
    452 
    453 #ifdef HAVE_LIBAVAHI_UI
    454  if (setting->opt1) {
    455  gfe->priv->avahi_service_type = (const gchar *)setting->opt1;
    456 
    457  hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    458  gtk_widget_show(hbox);
    459  gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0);
    460 
    461  widget = gtk_button_new_with_label("…");
    462  s = g_strdup_printf(_("Browse the network to find a %s server"), plugin->name);
    463  gtk_widget_set_tooltip_text(widget, s);
    464  g_free(s);
    465  gtk_widget_show(widget);
    466  gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0);
    467  g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_file_editor_browse_avahi), gfe);
    468 
    469  gtk_grid_attach(GTK_GRID(grid), hbox, 1, row, 1, 1);
    470  } else
    471 #endif
    472  {
    473  gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 1, 1);
    474  }
    475 }
    476 
    477 
    478 static GtkWidget *remmina_file_editor_create_password(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gchar *value, gchar *setting_name)
    479 {
    480  TRACE_CALL(__func__);
    481  GtkWidget *widget;
    482 
    483  widget = gtk_label_new(label);
    484  gtk_widget_show(widget);
    485 #if GTK_CHECK_VERSION(3, 12, 0)
    486  gtk_widget_set_margin_end(widget, 40);
    487 #else
    488  gtk_widget_set_margin_right(widget, 40);
    489 #endif
    490  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    491  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    492  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
    493 
    494  widget = gtk_entry_new();
    495  gtk_widget_show(widget);
    496  gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 1, 1);
    497  gtk_entry_set_max_length(GTK_ENTRY(widget), 0);
    498  gtk_entry_set_visibility(GTK_ENTRY(widget), FALSE);
    499  gtk_widget_set_hexpand(widget, TRUE);
    500  gtk_entry_set_activates_default(GTK_ENTRY(widget), TRUE);
    501  if (setting_name)
    502  gtk_widget_set_name(widget, setting_name);
    503 
    504  if (value)
    505  gtk_entry_set_text(GTK_ENTRY(widget), value);
    506  /* Password view Toogle*/
    507  if (setting_name) {
    508  gtk_entry_set_icon_from_icon_name(GTK_ENTRY(widget), GTK_ENTRY_ICON_SECONDARY, "org.remmina.Remmina-password-reveal-symbolic");
    509  gtk_entry_set_icon_activatable(GTK_ENTRY(widget), GTK_ENTRY_ICON_SECONDARY, TRUE);
    510  g_signal_connect(widget, "icon-press", G_CALLBACK(remmina_main_toggle_password_view), NULL);
    511  }
    512  return widget;
    513 }
    514 
    515 static void remmina_file_editor_update_resolution(GtkWidget *widget, RemminaFileEditor *gfe)
    516 {
    517  TRACE_CALL(__func__);
    518  gchar *res_str;
    519  res_str = g_strdup_printf("%dx%d",
    520  remmina_file_get_int(gfe->priv->remmina_file, "resolution_width", 0),
    521  remmina_file_get_int(gfe->priv->remmina_file, "resolution_height", 0));
    522  remmina_public_load_combo_text_d(gfe->priv->resolution_custom_combo, remmina_pref.resolutions,
    523  res_str, NULL);
    524  g_free(res_str);
    525 }
    526 
    527 static void remmina_file_editor_browse_resolution(GtkWidget *button, RemminaFileEditor *gfe)
    528 {
    529  TRACE_CALL(__func__);
    530 
    531  GtkDialog *dialog = remmina_string_list_new(FALSE, NULL);
    534  remmina_string_list_set_titles(_("Resolutions"), _("Configure the available resolutions"));
    535  gtk_window_set_transient_for(GTK_WINDOW(dialog), GTK_WINDOW(gfe));
    536  gtk_dialog_run(dialog);
    537  g_free(remmina_pref.resolutions);
    539  g_signal_connect(G_OBJECT(dialog), "destroy", G_CALLBACK(remmina_file_editor_update_resolution), gfe);
    540  gtk_widget_destroy(GTK_WIDGET(dialog));
    541 }
    542 
    544  GtkWidget *grid, gint row)
    545 {
    546  TRACE_CALL(__func__);
    547  GtkWidget *widget;
    548  GtkWidget *hbox;
    549  int resolution_w, resolution_h;
    550  gchar *res_str;
    552 
    553  res_mode = remmina_file_get_int(gfe->priv->remmina_file, "resolution_mode", RES_INVALID);
    554  resolution_w = remmina_file_get_int(gfe->priv->remmina_file, "resolution_width", -1);
    555  resolution_h = remmina_file_get_int(gfe->priv->remmina_file, "resolution_height", -1);
    556 
    557  /* If resolution_mode is non-existent (-1), then we try to calculate it
    558  * as we did before having resolution_mode */
    559  if (res_mode == RES_INVALID) {
    560  if (resolution_w <= 0 || resolution_h <= 0)
    561  res_mode = RES_USE_INITIAL_WINDOW_SIZE;
    562  else
    563  res_mode = RES_USE_CUSTOM;
    564  }
    565  if (res_mode == RES_USE_CUSTOM)
    566  res_str = g_strdup_printf("%dx%d", resolution_w, resolution_h);
    567  else
    568  res_str = NULL;
    569 
    570  widget = gtk_label_new(_("Resolution"));
    571  gtk_widget_show(widget);
    572  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    573  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    574  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
    575 
    576  hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    577  widget = gtk_radio_button_new_with_label(NULL, _("Use initial window size"));
    578  gtk_widget_show(widget);
    579  gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0);
    580  gfe->priv->resolution_iws_radio = widget;
    581  widget = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(gfe->priv->resolution_iws_radio), _("Use client resolution"));
    582  gtk_widget_show(widget);
    583  gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0);
    584  gfe->priv->resolution_auto_radio = widget;
    585  gtk_grid_attach(GTK_GRID(grid), hbox, 1, row, 1, 1);
    586  gtk_widget_show(hbox);
    587 
    588  hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    589  gtk_widget_show(hbox);
    590  gtk_grid_attach(GTK_GRID(grid), hbox, 1, row + 1, 1, 1);
    591 
    592  widget = gtk_radio_button_new_with_label_from_widget(GTK_RADIO_BUTTON(gfe->priv->resolution_iws_radio), _("Custom"));
    593  gtk_widget_show(widget);
    594  gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0);
    595  gfe->priv->resolution_custom_radio = widget;
    596 
    598  gtk_widget_show(widget);
    599  gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0);
    600  gfe->priv->resolution_custom_combo = widget;
    601 
    602  widget = gtk_button_new_with_label("…");
    603  gtk_widget_show(widget);
    604  gtk_box_pack_start(GTK_BOX(hbox), widget, FALSE, FALSE, 0);
    605  g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_file_editor_browse_resolution), gfe);
    606 
    607  g_signal_connect(G_OBJECT(gfe->priv->resolution_custom_radio), "toggled",
    608  G_CALLBACK(remmina_file_editor_button_on_toggled), gfe->priv->resolution_custom_combo);
    609 
    610  if (res_mode == RES_USE_CUSTOM)
    611  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gfe->priv->resolution_custom_radio), TRUE);
    612  else if (res_mode == RES_USE_CLIENT)
    613  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gfe->priv->resolution_auto_radio), TRUE);
    614  else
    615  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(gfe->priv->resolution_iws_radio), TRUE);
    616 
    617  gtk_widget_set_sensitive(gfe->priv->resolution_custom_combo, gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(gfe->priv->resolution_custom_radio)));
    618 
    619  g_free(res_str);
    620 }
    621 
    622 static GtkWidget *remmina_file_editor_create_text2(RemminaFileEditor *gfe, GtkWidget *grid,
    623  gint row, gint col, const gchar *label, const gchar *value, gint left,
    624  gint right, gchar *setting_name)
    625 {
    626  TRACE_CALL(__func__);
    627  GtkWidget *widget;
    628 
    629  widget = gtk_label_new(label);
    630  gtk_widget_show(widget);
    631 #if GTK_CHECK_VERSION(3, 12, 0)
    632  gtk_widget_set_margin_start(widget, left);
    633  gtk_widget_set_margin_end(widget, right);
    634 #else
    635  gtk_widget_set_margin_left(widget, left);
    636  gtk_widget_set_margin_right(widget, right);
    637 #endif
    638  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    639  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    640  gtk_grid_attach(GTK_GRID(grid), widget, col, row, 1, 1);
    641 
    642  widget = gtk_entry_new();
    643  gtk_widget_show(widget);
    644  gtk_grid_attach(GTK_GRID(grid), widget, col + 1, row, 1, 1);
    645  gtk_entry_set_max_length(GTK_ENTRY(widget), 300);
    646  gtk_widget_set_hexpand(widget, TRUE);
    647  if (setting_name)
    648  gtk_widget_set_name(widget, setting_name);
    649 
    650  if (value)
    651  gtk_entry_set_text(GTK_ENTRY(widget), value);
    652 
    653  return widget;
    654 }
    655 
    656 static GtkWidget *remmina_file_editor_create_text(RemminaFileEditor *gfe, GtkWidget *grid,
    657  gint row, gint col, const gchar *label, const gchar *value,
    658  gchar *setting_name)
    659 {
    660  TRACE_CALL(__func__);
    661  return remmina_file_editor_create_text2(gfe, grid, row, col, label, value, 0, 40,
    662  setting_name);
    663 }
    664 
    665 static GtkWidget *remmina_file_editor_create_textarea(RemminaFileEditor *gfe, GtkWidget *grid,
    666  gint row, gint col, const gchar *label, const gchar *value,
    667  gchar *setting_name)
    668 {
    669  TRACE_CALL(__func__);
    670  GtkWidget *widget;
    671  GtkTextView *view;
    672  GtkTextBuffer *buffer;
    673  GtkTextIter start;
    674 
    675  widget = gtk_text_view_new();
    676  view = GTK_TEXT_VIEW(widget);
    677  gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(view), GTK_WRAP_WORD);
    678  gtk_text_view_set_top_margin(GTK_TEXT_VIEW(view), 20);
    679  gtk_text_view_set_bottom_margin(GTK_TEXT_VIEW(view), 20);
    680  gtk_text_view_set_left_margin(GTK_TEXT_VIEW(view), 20);
    681  gtk_text_view_set_right_margin(GTK_TEXT_VIEW(view), 20);
    682  gtk_text_view_set_monospace(view, TRUE);
    683  if (setting_name)
    684  gtk_widget_set_name(widget, setting_name);
    685  if (value) {
    686  buffer = gtk_text_view_get_buffer(view);
    687  gtk_text_buffer_set_text(buffer, value, -1);
    688  gtk_text_buffer_get_start_iter(buffer, &start);
    689  gtk_text_buffer_place_cursor(buffer, &start);
    690  }
    691  gtk_widget_show(widget);
    692  gtk_widget_set_hexpand(widget, TRUE);
    693  gtk_widget_set_size_request(GTK_WIDGET(view), 320, 300);
    694  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
    695  return widget;
    696 }
    697 
    698 static GtkWidget *remmina_file_editor_create_select(RemminaFileEditor *gfe, GtkWidget *grid,
    699  gint row, gint col, const gchar *label, const gpointer *list,
    700  const gchar *value, gchar *setting_name)
    701 {
    702  TRACE_CALL(__func__);
    703  GtkWidget *widget;
    704 
    705  widget = gtk_label_new(label);
    706  gtk_widget_show(widget);
    707  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    708  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    709  if (setting_name)
    710  gtk_widget_set_name(widget, setting_name);
    711  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
    712 
    713  widget = remmina_public_create_combo_map(list, value, FALSE, gfe->priv->plugin->domain);
    714  gtk_widget_show(widget);
    715  gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 1, 1);
    716 
    717  return widget;
    718 }
    719 
    720 static GtkWidget *remmina_file_editor_create_combo(RemminaFileEditor *gfe, GtkWidget *grid,
    721  gint row, gint col, const gchar *label, const gchar *list,
    722  const gchar *value, gchar *setting_name)
    723 {
    724  TRACE_CALL(__func__);
    725  GtkWidget *widget;
    726 
    727  widget = gtk_label_new(label);
    728  gtk_widget_show(widget);
    729  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    730  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    731  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
    732 
    733  widget = remmina_public_create_combo_entry(list, value, FALSE);
    734  gtk_widget_show(widget);
    735  gtk_widget_set_hexpand(widget, TRUE);
    736  if (setting_name)
    737  gtk_widget_set_name(widget, setting_name);
    738  gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 1, 1);
    739 
    740  return widget;
    741 }
    742 
    743 static GtkWidget *remmina_file_editor_create_check(RemminaFileEditor *gfe, GtkWidget *grid,
    744  gint row, gint top, const gchar *label, gboolean value,
    745  gchar *setting_name)
    746 {
    747  TRACE_CALL(__func__);
    748  GtkWidget *widget;
    749  widget = gtk_check_button_new_with_label(label);
    750  gtk_widget_show(widget);
    751  if (setting_name)
    752  gtk_widget_set_name(widget, setting_name);
    753  gtk_grid_attach(GTK_GRID(grid), widget, top, row, 1, 1);
    754 
    755  if (value)
    756  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(widget), TRUE);
    757 
    758  return widget;
    759 }
    760 
    770 static GtkWidget *
    771 remmina_file_editor_create_chooser(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label,
    772  const gchar *value, gint type, gchar *setting_name)
    773 {
    774  TRACE_CALL(__func__);
    775  GtkWidget *check;
    776  GtkWidget *widget;
    777  GtkWidget *hbox;
    778 
    779  widget = gtk_label_new(label);
    780  gtk_widget_show(widget);
    781  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    782  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    783  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
    784 
    785  hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
    786  gtk_widget_show(hbox);
    787  gtk_grid_attach(GTK_GRID(grid), hbox, 1, row, 1, 1);
    788 
    789  check = gtk_check_button_new();
    790  gtk_widget_show(check);
    791  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), (value && value[0] == '/'));
    792  gtk_box_pack_start(GTK_BOX(hbox), check, FALSE, FALSE, 0);
    793 
    794  widget = gtk_file_chooser_button_new(label, type);
    795  if (setting_name)
    796  gtk_widget_set_name(widget, setting_name);
    797  gtk_widget_show(widget);
    798  if (value)
    799  gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(widget), value);
    800  gtk_box_pack_start(GTK_BOX(hbox), widget, TRUE, TRUE, 0);
    801 
    802  g_signal_connect(G_OBJECT(check), "toggled", G_CALLBACK(remmina_file_editor_button_on_toggled), widget);
    803  remmina_file_editor_button_on_toggled(GTK_TOGGLE_BUTTON(check), widget);
    804 
    805  return widget;
    806 }
    807 
    808 // used to filter out invalid characters for REMMINA_PROTOCOL_SETTING_TYPE_INT
    809 void remmina_file_editor_int_setting_filter(GtkEditable *editable, const gchar *text,
    810  gint length, gint *position, gpointer data)
    811 {
    812  for (int i = 0; i < length; i++) {
    813  if (!isdigit(text[i]) && text[i] != '-') {
    814  g_signal_stop_emission_by_name(G_OBJECT(editable), "insert-text");
    815  return;
    816  }
    817  }
    818 }
    819 
    820 // used to filter out invalid characters for REMMINA_PROTOCOL_SETTING_TYPE_DOUBLE
    821 // '.' and ',' can't be used interchangeably! It depends on the language setting
    822 // of the user.
    823 void remmina_file_editor_double_setting_filter(GtkEditable *editable, const gchar *text,
    824  gint length, gint *position, gpointer data)
    825 {
    826  for (int i = 0; i < length; i++) {
    827  if (!isdigit(text[i]) && text[i] != '-' && text[i] != '.' && text[i] != ',') {
    828  g_signal_stop_emission_by_name(G_OBJECT(editable), "insert-text");
    829  return;
    830  }
    831  }
    832 }
    833 
    834 static GtkWidget *remmina_file_editor_create_int(RemminaFileEditor *gfe, GtkWidget *grid,
    835  gint row, gint col, const gchar *label, const gint value,
    836  gint left, gint right, gchar *setting_name)
    837 {
    838  TRACE_CALL(__func__);
    839  GtkWidget *widget;
    840 
    841  widget = gtk_label_new(label);
    842  gtk_widget_show(widget);
    843 #if GTK_CHECK_VERSION(3, 12, 0)
    844  gtk_widget_set_margin_start(widget, left);
    845  gtk_widget_set_margin_end(widget, right);
    846 #else
    847  gtk_widget_set_margin_left(widget, left);
    848  gtk_widget_set_margin_right(widget, right);
    849 #endif
    850  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    851  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    852  gtk_grid_attach(GTK_GRID(grid), widget, col, row, 1, 1);
    853 
    854  widget = gtk_entry_new();
    855  gtk_widget_show(widget);
    856  gtk_grid_attach(GTK_GRID(grid), widget, col + 1, row, 1, 1);
    857  gtk_entry_set_max_length(GTK_ENTRY(widget), 300);
    858  gtk_widget_set_hexpand(widget, TRUE);
    859  if (setting_name)
    860  gtk_widget_set_name(widget, setting_name);
    861 
    862  // Convert int to str.
    863  int length = snprintf(NULL, 0, "%d", value) + 1; // +1 '\0' byte
    864  char *str = malloc(length);
    865  snprintf(str, length, "%d", value);
    866 
    867  gtk_entry_set_text(GTK_ENTRY(widget), str);
    868  free(str);
    869 
    870  g_signal_connect(G_OBJECT(widget), "insert-text",
    871  G_CALLBACK(remmina_file_editor_int_setting_filter), NULL);
    872 
    873  return widget;
    874 }
    875 
    877  GtkWidget *grid, gint row, gint col,
    878  const gchar *label, gdouble value, gint left,
    879  gint right, gchar *setting_name)
    880 {
    881  TRACE_CALL(__func__);
    882  GtkWidget *widget;
    883 
    884  widget = gtk_label_new(label);
    885  gtk_widget_show(widget);
    886 #if GTK_CHECK_VERSION(3, 12, 0)
    887  gtk_widget_set_margin_start(widget, left);
    888  gtk_widget_set_margin_end(widget, right);
    889 #else
    890  gtk_widget_set_margin_left(widget, left);
    891  gtk_widget_set_margin_right(widget, right);
    892 #endif
    893  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    894  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    895  gtk_grid_attach(GTK_GRID(grid), widget, col, row, 1, 1);
    896 
    897  widget = gtk_entry_new();
    898  gtk_widget_show(widget);
    899  gtk_grid_attach(GTK_GRID(grid), widget, col + 1, row, 1, 1);
    900  gtk_entry_set_max_length(GTK_ENTRY(widget), 300);
    901  gtk_widget_set_hexpand(widget, TRUE);
    902  if (setting_name)
    903  gtk_widget_set_name(widget, setting_name);
    904 
    905  // Convert double to str.
    906  int length = snprintf(NULL, 0, "%.8g", value) + 1; // +1 '\0' byte
    907  char *str = malloc(length);
    908  snprintf(str, length, "%f", value);
    909 
    910  gtk_entry_set_text(GTK_ENTRY(widget), str);
    911  free(str);
    912 
    913  g_signal_connect(G_OBJECT(widget), "insert-text",
    915 
    916  return widget;
    917 }
    918 
    919 gdouble remmina_file_get_double(RemminaFile *remminafile, const gchar *setting, gfloat default_value);
    920 
    921 static void remmina_file_editor_create_settings(RemminaFileEditor *gfe, GtkWidget *grid,
    922  const RemminaProtocolSetting *settings)
    923 {
    924  TRACE_CALL(__func__);
    925  RemminaFileEditorPriv *priv = gfe->priv;
    926  GtkWidget *widget;
    927  gint grid_row = 0;
    928  gint grid_column = 0;
    929  gchar **strarr;
    930  gchar *setting_name;
    931  const gchar *escaped;
    932 
    933  while (settings->type != REMMINA_PROTOCOL_SETTING_TYPE_END) {
    934  setting_name = (gchar *)(remmina_plugin_manager_get_canonical_setting_name(settings));
    935  switch (settings->type) {
    937  remmina_file_editor_create_server(gfe, settings, grid, grid_row);
    938  break;
    939 
    941  widget = remmina_file_editor_create_password(gfe, grid, grid_row, 0,
    942  g_dgettext(priv->plugin->domain, settings->label),
    943  remmina_file_get_string(priv->remmina_file, setting_name),
    944  setting_name);
    945  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    946  grid_row++;
    947  break;
    948 
    950  remmina_file_editor_create_resolution(gfe, settings, grid, grid_row);
    951  grid_row += 1;
    952  break;
    953 
    955  strarr = remmina_pref_keymap_groups();
    956  priv->keymap_combo = remmina_file_editor_create_select(gfe, grid,
    957  grid_row + 1, 0,
    958  _("Keyboard mapping"), (const gpointer *)strarr,
    959  remmina_file_get_string(priv->remmina_file, "keymap"),
    960  setting_name);
    961  g_strfreev(strarr);
    962  grid_row++;
    963  break;
    964 
    966  widget = remmina_file_editor_create_text(gfe, grid, grid_row, 0,
    967  g_dgettext(priv->plugin->domain, settings->label),
    968  remmina_file_get_string(priv->remmina_file, setting_name),
    969  setting_name);
    970  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    971  if (settings->opt2)
    972  gtk_widget_set_tooltip_text(widget, _((const gchar *)settings->opt2));
    973  grid_row++;
    974  break;
    975 
    977  escaped = remmina_file_get_string(priv->remmina_file, setting_name);
    978  escaped = g_uri_unescape_string(escaped, NULL);
    979  widget = remmina_file_editor_create_textarea(gfe, grid, grid_row, 0,
    980  g_dgettext(priv->plugin->domain, settings->label), escaped,
    981  setting_name);
    982  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    983  grid_row++;
    984  break;
    985 
    987  widget = remmina_file_editor_create_select(gfe, grid, grid_row, 0,
    988  g_dgettext(priv->plugin->domain, settings->label),
    989  (const gpointer *)settings->opt1,
    990  remmina_file_get_string(priv->remmina_file, setting_name),
    991  setting_name);
    992  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    993  if (settings->opt2)
    994  gtk_widget_set_tooltip_text(widget, _((const gchar *)settings->opt2));
    995  break;
    996 
    998  widget = remmina_file_editor_create_combo(gfe, grid, grid_row, 0,
    999  g_dgettext(priv->plugin->domain, settings->label),
    1000  (const gchar *)settings->opt1,
    1001  remmina_file_get_string(priv->remmina_file, setting_name),
    1002  setting_name);
    1003  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    1004  if (settings->opt2)
    1005  gtk_widget_set_tooltip_text(widget, _((const gchar *)settings->opt2));
    1006  break;
    1007 
    1009  widget = remmina_file_editor_create_check(gfe, grid, grid_row, grid_column,
    1010  g_dgettext(priv->plugin->domain, settings->label),
    1011  remmina_file_get_int(priv->remmina_file, setting_name, FALSE),
    1012  setting_name);
    1013  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    1014  if (settings->opt2)
    1015  gtk_widget_set_tooltip_text(widget, _((const gchar *)settings->opt2));
    1016  break;
    1017 
    1019  widget = remmina_file_editor_create_chooser(gfe, grid, grid_row, 0,
    1020  g_dgettext(priv->plugin->domain, settings->label),
    1021  remmina_file_get_string(priv->remmina_file, setting_name),
    1022  GTK_FILE_CHOOSER_ACTION_OPEN, setting_name);
    1023  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    1024  if (settings->opt2)
    1025  gtk_widget_set_tooltip_text(widget, _((const gchar *)settings->opt2));
    1026  break;
    1027 
    1029  widget = remmina_file_editor_create_chooser(gfe, grid, grid_row, 0,
    1030  g_dgettext(priv->plugin->domain, settings->label),
    1031  remmina_file_get_string(priv->remmina_file, setting_name),
    1032  GTK_FILE_CHOOSER_ACTION_SELECT_FOLDER,
    1033  setting_name);
    1034  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    1035  if (settings->opt2)
    1036  gtk_widget_set_tooltip_text(widget, _((const gchar *)settings->opt2));
    1037  break;
    1039  widget = remmina_file_editor_create_int(gfe, grid, grid_row, 0,
    1040  g_dgettext(priv->plugin->domain, settings->label),
    1041  remmina_file_get_int(priv->remmina_file, setting_name, 0),
    1042  0, 40, setting_name);
    1043  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    1044  if (settings->opt2)
    1045  gtk_widget_set_tooltip_text(widget, _((const gchar *)settings->opt2));
    1046  grid_row++;
    1047  break;
    1049  widget = remmina_file_editor_create_double(gfe, grid, grid_row, 0,
    1050  g_dgettext(priv->plugin->domain, settings->label),
    1051  remmina_file_get_double(priv->remmina_file, setting_name, 0.0f),
    1052  0, 40, setting_name);
    1053  g_hash_table_insert(priv->setting_widgets, setting_name, widget);
    1054  if (settings->opt2)
    1055  gtk_widget_set_tooltip_text(widget, _((const gchar *)settings->opt2));
    1056  grid_row++;
    1057  break;
    1058 
    1059  default:
    1060  break;
    1061  }
    1062  /* If the setting wants compactness, move to the next column */
    1063  if (settings->compact)
    1064  grid_column++;
    1065  /* Add a new settings row and move to the first column
    1066  * if the setting doesn’t want the compactness
    1067  * or we already have two columns */
    1068  if (!settings->compact || grid_column > 1) {
    1069  grid_row++;
    1070  grid_column = 0;
    1071  }
    1072  settings++;
    1073  }
    1074 }
    1075 
    1077 {
    1078  TRACE_CALL(__func__);
    1079  RemminaFileEditorPriv *priv = gfe->priv;
    1080  GtkWidget *grid;
    1081  GtkWidget *widget;
    1082  const gchar *cs;
    1083 
    1084  /* The Behavior tab (implementation) */
    1085  grid = remmina_file_editor_create_notebook_tab(gfe, NULL, _("Behavior"), 20, 2);
    1086 
    1087  /* Execute Command frame */
    1088  remmina_public_create_group(GTK_GRID(grid), _("Execute a Command"), 0, 1, 2);
    1089 
    1090  /* PRE connection command */
    1091  cs = remmina_file_get_string(priv->remmina_file, "precommand");
    1092  widget = remmina_file_editor_create_text2(gfe, grid, 2, 0, _("Before connecting"), cs, 24, 26, "precommand");
    1093  priv->behavior_precommand_entry = widget;
    1094  gtk_entry_set_placeholder_text(GTK_ENTRY(widget), _("command %h %u %t %U %p %g --option"));
    1095  gtk_widget_set_tooltip_markup(widget, _(cmd_tips));
    1096 
    1097  /* POST connection command */
    1098  cs = remmina_file_get_string(priv->remmina_file, "postcommand");
    1099  widget = remmina_file_editor_create_text2(gfe, grid, 3, 0, _("After connecting"), cs, 24, 16, "postcommand");
    1100  priv->behavior_postcommand_entry = widget;
    1101  gtk_entry_set_placeholder_text(GTK_ENTRY(widget), _("/path/to/command -opt1 arg %h %u %t -opt2 %U %p %g"));
    1102  gtk_widget_set_tooltip_markup(widget, _(cmd_tips));
    1103 
    1104  /* Startup frame */
    1105  remmina_public_create_group(GTK_GRID(grid), _("Start-up"), 4, 1, 2);
    1106 
    1107  /* Autostart profile option */
    1108  priv->behavior_autostart_check = remmina_file_editor_create_check(gfe, grid, 6, 1, _("Auto-start this profile"),
    1109  remmina_file_get_int(priv->remmina_file, "enable-autostart", FALSE), "enable-autostart");
    1110 
    1111  /* Startup frame */
    1112  remmina_public_create_group(GTK_GRID(grid), _("Connection profile security"), 8, 1, 2);
    1113 
    1114  /* Autostart profile option */
    1115  priv->behavior_lock_check = remmina_file_editor_create_check(gfe, grid, 10, 1, _("Require password to connect or edit the profile"),
    1116  remmina_file_get_int(priv->remmina_file, "profile-lock", FALSE), "profile-lock");
    1117 }
    1118 
    1119 #ifdef HAVE_LIBSSH
    1120 static gpointer ssh_tunnel_auth_list[] =
    1121 {
    1122  "0", N_("Password"),
    1123  "1", N_("SSH identity file"),
    1124  "2", N_("SSH agent"),
    1125  "3", N_("Public key (automatic)"),
    1126  "4", N_("Kerberos (GSSAPI)"),
    1127  NULL
    1128 };
    1129 #endif
    1130 
    1132 {
    1133  TRACE_CALL(__func__);
    1134 #ifdef HAVE_LIBSSH
    1135  RemminaFileEditorPriv *priv = gfe->priv;
    1136  GtkWidget *grid;
    1137  GtkWidget *widget;
    1138  const gchar *cs;
    1139  gchar *s;
    1140  gchar *p;
    1141  gint row = 0;
    1142 
    1143  if (ssh_setting == REMMINA_PROTOCOL_SSH_SETTING_NONE)
    1144  return;
    1145 
    1146  /* The SSH tab (implementation) */
    1147  grid = remmina_file_editor_create_notebook_tab(gfe, NULL,
    1148  _("SSH Tunnel"), 9, 3);
    1149  widget = gtk_toggle_button_new_with_label(_("Enable SSH tunnel"));
    1150  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    1151  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
    1152  g_signal_connect(G_OBJECT(widget), "toggled",
    1154  priv->ssh_tunnel_enabled_check = widget;
    1155 
    1156  widget = gtk_check_button_new_with_label(_("Tunnel via loopback address"));
    1157  gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 2, 1);
    1158  priv->ssh_tunnel_loopback_check = widget;
    1159 
    1160  // 1
    1161  row++;
    1162  /* SSH Server group */
    1163 
    1164  switch (ssh_setting) {
    1166  s = g_strdup_printf(_("Same server at port %i"), DEFAULT_SSH_PORT);
    1167  widget = gtk_radio_button_new_with_label(NULL, s);
    1168  g_free(s);
    1169  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 3, 1);
    1170  priv->ssh_tunnel_server_default_radio = widget;
    1171  // 2
    1172  row++;
    1173 
    1174  widget = gtk_radio_button_new_with_label_from_widget(
    1175  GTK_RADIO_BUTTON(priv->ssh_tunnel_server_default_radio), _("Custom"));
    1176  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
    1177  g_signal_connect(G_OBJECT(widget), "toggled",
    1179  priv->ssh_tunnel_server_custom_radio = widget;
    1180 
    1181  widget = gtk_entry_new();
    1182  gtk_entry_set_max_length(GTK_ENTRY(widget), 100);
    1183  gtk_widget_set_tooltip_markup(widget, _(server_tips2));
    1184  gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 2, 1);
    1185  priv->ssh_tunnel_server_entry = widget;
    1186  // 3
    1187  row++;
    1188  break;
    1189 
    1191  priv->ssh_tunnel_server_default_radio = NULL;
    1192  priv->ssh_tunnel_server_custom_radio = NULL;
    1193 
    1194  priv->ssh_tunnel_server_entry = remmina_file_editor_create_text(gfe, grid, 1, 0,
    1195  _("Server"), NULL, "ssh_reverse_tunnel_server");
    1196  gtk_widget_set_tooltip_markup(priv->ssh_tunnel_server_entry, _(server_tips));
    1197  // 2
    1198  row++;
    1199  break;
    1202  priv->ssh_tunnel_server_default_radio = NULL;
    1203  priv->ssh_tunnel_server_custom_radio = NULL;
    1204  priv->ssh_tunnel_server_entry = NULL;
    1205 
    1206  break;
    1207 
    1208  default:
    1209  break;
    1210  }
    1211 
    1212  /* This is not used? */
    1213  p = remmina_public_combo_get_active_text(GTK_COMBO_BOX(priv->protocol_combo));
    1214  if (ssh_setting == REMMINA_PROTOCOL_SSH_SETTING_SFTP) {
    1215  widget = remmina_file_editor_create_text(gfe, grid, row, 1,
    1216  _("Start-up path"), NULL, "start-up-path");
    1217  cs = remmina_file_get_string(priv->remmina_file, "execpath");
    1218  gtk_entry_set_text(GTK_ENTRY(widget), cs ? cs : "");
    1219  g_hash_table_insert(priv->setting_widgets, "execpath", widget);
    1220  // 2
    1221  row++;
    1222  }
    1223 
    1224  /* SSH Authentication frame */
    1225  remmina_public_create_group(GTK_GRID(grid), _("SSH Authentication"), row, 6, 1);
    1226  // 5
    1227  row += 2;
    1228 
    1229  priv->ssh_tunnel_auth_combo = remmina_file_editor_create_select(gfe, grid, row, 0,
    1230  _("Authentication type"),
    1231  (const gpointer *)ssh_tunnel_auth_list,
    1232  remmina_file_get_string(priv->remmina_file, "ssh_tunnel_auth"), "ssh_tunnel_auth");
    1233  row++;
    1234 
    1235  if (ssh_setting == REMMINA_PROTOCOL_SSH_SETTING_TUNNEL ||
    1237  priv->ssh_tunnel_username_entry =
    1238  remmina_file_editor_create_text(gfe, grid, row, 0,
    1239  _("Username"), NULL, "ssh_tunnel_username");
    1240  // 5
    1241  row++;
    1242  }
    1243 
    1244  widget = remmina_file_editor_create_password(gfe, grid, row, 0,
    1245  _("Password"),
    1246  remmina_file_get_string(priv->remmina_file, "ssh_tunnel_password"),
    1247  "ssh_tunnel_password");
    1248  priv->ssh_tunnel_auth_password = widget;
    1249  row++;
    1250 
    1251  priv->ssh_tunnel_privatekey_chooser = remmina_file_editor_create_chooser(gfe, grid, row, 0,
    1252  _("SSH private key file"),
    1253  remmina_file_get_string(priv->remmina_file, "ssh_tunnel_privatekey"),
    1254  GTK_FILE_CHOOSER_ACTION_OPEN, "ssh_tunnel_privatekey");
    1255  row++;
    1256 
    1257  priv->ssh_tunnel_certfile_chooser = remmina_file_editor_create_chooser(gfe, grid, row, 0,
    1258  _("SSH certificate file"),
    1259  remmina_file_get_string(priv->remmina_file, "ssh_tunnel_certfile"),
    1260  GTK_FILE_CHOOSER_ACTION_OPEN, "ssh_tunnel_certfile");
    1261  row++;
    1262 
    1263  widget = gtk_label_new(_("Password to unlock private key"));
    1264  gtk_grid_attach(GTK_GRID(grid), widget, 0, row, 1, 1);
    1265  widget = gtk_entry_new();
    1266  gtk_grid_attach(GTK_GRID(grid), widget, 1, row, 2, 1);
    1267  gtk_entry_set_max_length(GTK_ENTRY(widget), 300);
    1268  gtk_entry_set_visibility(GTK_ENTRY(widget), FALSE);
    1269  gtk_widget_set_hexpand(widget, TRUE);
    1270  priv->ssh_tunnel_passphrase = widget;
    1271  row++;
    1272 
    1273  /* Set the values */
    1274  cs = remmina_file_get_string(priv->remmina_file, "ssh_tunnel_server");
    1275  if (ssh_setting == REMMINA_PROTOCOL_SSH_SETTING_TUNNEL) {
    1276  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->ssh_tunnel_enabled_check),
    1277  remmina_file_get_int(priv->remmina_file, "ssh_tunnel_enabled", FALSE));
    1278  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->ssh_tunnel_loopback_check),
    1279  remmina_file_get_int(priv->remmina_file, "ssh_tunnel_loopback", FALSE));
    1280 
    1281  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cs ? priv->ssh_tunnel_server_custom_radio : priv->ssh_tunnel_server_default_radio), TRUE);
    1282  gtk_entry_set_text(GTK_ENTRY(priv->ssh_tunnel_server_entry),
    1283  cs ? cs : "");
    1284  } else if (ssh_setting == REMMINA_PROTOCOL_SSH_SETTING_REVERSE_TUNNEL) {
    1285  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->ssh_tunnel_enabled_check),
    1286  remmina_file_get_int(priv->remmina_file, "ssh_tunnel_enabled", FALSE));
    1287  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(priv->ssh_tunnel_loopback_check),
    1288  remmina_file_get_int(priv->remmina_file, "ssh_tunnel_loopback", FALSE));
    1289  gtk_entry_set_text(GTK_ENTRY(priv->ssh_tunnel_server_entry),
    1290  cs ? cs : "");
    1291  }
    1292 
    1294  gtk_widget_show_all(grid);
    1295  g_free(p);
    1296 #endif
    1297 }
    1298 
    1300 {
    1301  TRACE_CALL(__func__);
    1302  RemminaFileEditorPriv *priv = gfe->priv;
    1303  GtkWidget *grid;
    1304 
    1305  static const RemminaProtocolSetting notes_settings[] =
    1306  {
    1307  { REMMINA_PROTOCOL_SETTING_TYPE_TEXTAREA, "notes_text", NULL, FALSE, NULL, NULL },
    1308  { REMMINA_PROTOCOL_SETTING_TYPE_END, NULL, NULL, FALSE, NULL, NULL }
    1309  };
    1310 
    1312 
    1313  /* The Basic tab */
    1314  if (priv->plugin->basic_settings) {
    1315  grid = remmina_file_editor_create_notebook_tab(gfe, NULL, _("Basic"), 20, 2);
    1316  remmina_file_editor_create_settings(gfe, grid, priv->plugin->basic_settings);
    1317  }
    1318 
    1319  /* The Advanced tab */
    1320  if (priv->plugin->advanced_settings) {
    1321  grid = remmina_file_editor_create_notebook_tab(gfe, NULL, _("Advanced"), 20, 2);
    1322  remmina_file_editor_create_settings(gfe, grid, priv->plugin->advanced_settings);
    1323  }
    1324 
    1325  /* The Behavior tab */
    1327 
    1328  /* The SSH tab */
    1329  remmina_file_editor_create_ssh_tunnel_tab(gfe, priv->plugin->ssh_setting);
    1330 
    1331  /* Notes tab */
    1332  grid = remmina_file_editor_create_notebook_tab(gfe, NULL, _("Notes"), 1, 1);
    1333  remmina_file_editor_create_settings(gfe, grid, notes_settings);
    1334 }
    1335 
    1337 {
    1338  TRACE_CALL(__func__);
    1339  RemminaFileEditorPriv *priv = gfe->priv;
    1340  gchar *protocol;
    1341 
    1342  if (priv->config_container) {
    1343  gtk_widget_destroy(priv->config_container);
    1344  priv->config_container = NULL;
    1345  gtk_widget_destroy(priv->config_viewport);
    1346  priv->config_viewport = NULL;
    1347  gtk_widget_destroy(priv->config_scrollable);
    1348  priv->config_scrollable = NULL;
    1349  }
    1350 
    1351  priv->server_combo = NULL;
    1352  priv->resolution_iws_radio = NULL;
    1353  priv->resolution_auto_radio = NULL;
    1354  priv->resolution_custom_radio = NULL;
    1355  priv->resolution_custom_combo = NULL;
    1356  priv->keymap_combo = NULL;
    1357 
    1358  priv->ssh_tunnel_enabled_check = NULL;
    1359  priv->ssh_tunnel_loopback_check = NULL;
    1360  priv->ssh_tunnel_server_default_radio = NULL;
    1361  priv->ssh_tunnel_server_custom_radio = NULL;
    1362  priv->ssh_tunnel_server_entry = NULL;
    1363  priv->ssh_tunnel_username_entry = NULL;
    1364  priv->ssh_tunnel_auth_combo = NULL;
    1365  priv->ssh_tunnel_auth_password = NULL;
    1366  priv->ssh_tunnel_privatekey_chooser = NULL;
    1367  priv->ssh_tunnel_certfile_chooser = NULL;
    1368 
    1369  g_hash_table_remove_all(priv->setting_widgets);
    1370 
    1371  protocol = remmina_public_combo_get_active_text(combo);
    1372  if (protocol) {
    1374  protocol);
    1375  g_free(protocol);
    1377  }
    1378 }
    1379 
    1381 {
    1382  TRACE_CALL(__func__);
    1383  RemminaFileEditorPriv *priv = gfe->priv;
    1384 
    1385  remmina_file_set_string(priv->remmina_file, "precommand", gtk_entry_get_text(GTK_ENTRY(priv->behavior_precommand_entry)));
    1386  remmina_file_set_string(priv->remmina_file, "postcommand", gtk_entry_get_text(GTK_ENTRY(priv->behavior_postcommand_entry)));
    1387 
    1388  gboolean autostart_enabled = (priv->behavior_autostart_check ? gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->behavior_autostart_check)) : FALSE);
    1389  remmina_file_set_int(priv->remmina_file, "enable-autostart", autostart_enabled);
    1390  gboolean lock_enabled = (priv->behavior_lock_check ? gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->behavior_lock_check)) : FALSE);
    1391  remmina_file_set_int(priv->remmina_file, "profile-lock", lock_enabled);
    1392 }
    1393 
    1395 {
    1396  TRACE_CALL(__func__);
    1397  RemminaFileEditorPriv *priv = gfe->priv;
    1398  gboolean ssh_tunnel_enabled;
    1399  int ssh_tunnel_auth;
    1400 
    1401  ssh_tunnel_enabled = (priv->ssh_tunnel_enabled_check ? gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->ssh_tunnel_enabled_check)) : FALSE);
    1402  remmina_file_set_int(priv->remmina_file,
    1403  "ssh_tunnel_loopback",
    1404  (priv->ssh_tunnel_loopback_check ? gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->ssh_tunnel_loopback_check)) : FALSE));
    1405  remmina_file_set_int(priv->remmina_file, "ssh_tunnel_enabled", ssh_tunnel_enabled);
    1406  remmina_file_set_string(priv->remmina_file, "ssh_tunnel_auth",
    1407  remmina_public_combo_get_active_text(GTK_COMBO_BOX(priv->ssh_tunnel_auth_combo)));
    1408  remmina_file_set_string(priv->remmina_file, "ssh_tunnel_username",
    1409  (ssh_tunnel_enabled ? gtk_entry_get_text(GTK_ENTRY(priv->ssh_tunnel_username_entry)) : NULL));
    1411  priv->remmina_file,
    1412  "ssh_tunnel_server",
    1413  (ssh_tunnel_enabled && priv->ssh_tunnel_server_entry && (priv->ssh_tunnel_server_custom_radio == NULL || gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->ssh_tunnel_server_custom_radio))) ? gtk_entry_get_text(GTK_ENTRY(priv->ssh_tunnel_server_entry)) : NULL));
    1414 
    1415  ssh_tunnel_auth = gtk_combo_box_get_active(GTK_COMBO_BOX(priv->ssh_tunnel_auth_combo));
    1416 
    1418  priv->remmina_file,
    1419  "ssh_tunnel_auth",
    1420  ssh_tunnel_auth);
    1422  priv->remmina_file,
    1423  "ssh_tunnel_privatekey",
    1424  (priv->ssh_tunnel_privatekey_chooser ? gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(priv->ssh_tunnel_privatekey_chooser)) : NULL));
    1425 
    1427  priv->remmina_file,
    1428  "ssh_tunnel_certfile",
    1429  (priv->ssh_tunnel_certfile_chooser ? gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(priv->ssh_tunnel_certfile_chooser)) : NULL));
    1430 
    1432  priv->remmina_file,
    1433  "ssh_tunnel_password",
    1434  (ssh_tunnel_enabled && (ssh_tunnel_auth == SSH_AUTH_PASSWORD)) ? gtk_entry_get_text(GTK_ENTRY(priv->ssh_tunnel_auth_password)) : NULL);
    1435 
    1437  priv->remmina_file,
    1438  "ssh_tunnel_passphrase",
    1439  (ssh_tunnel_enabled && (ssh_tunnel_auth == SSH_AUTH_PUBLICKEY || ssh_tunnel_auth == SSH_AUTH_AUTO_PUBLICKEY)) ? gtk_entry_get_text(GTK_ENTRY(priv->ssh_tunnel_passphrase)) : NULL);
    1440 }
    1441 
    1443  gchar * setting_name_to_validate,
    1444  gconstpointer value,
    1445  GError ** err)
    1446 {
    1447  if (!setting_name_to_validate || !value || !gfe) {
    1448  if (!setting_name_to_validate) {
    1449  g_critical(_("(%s: %i): Can't validate setting '%s' since 'value' or 'gfe' "
    1450  "are NULL!"),
    1451  __func__, __LINE__, setting_name_to_validate);
    1452  } else {
    1453  g_critical(_("(%s: %i): Can't validate user input since "
    1454  "'setting_name_to_validate', 'value' or 'gfe' are NULL!"),
    1455  __func__, __LINE__);
    1456  }
    1457  g_set_error(err, 1, 1, _("Internal error."));
    1458  return FALSE;
    1459  }
    1460 
    1461  if (strcmp(setting_name_to_validate, "notes_text") == 0) {
    1462  // Not a plugin setting. Bail out early.
    1463  return TRUE;
    1464  }
    1465 
    1466  const RemminaProtocolSetting *setting_iter;
    1467  RemminaProtocolPlugin *protocol_plugin;
    1468  RemminaFileEditorPriv *priv = gfe->priv;
    1469  protocol_plugin = priv->plugin;
    1470 
    1471  setting_iter = protocol_plugin->basic_settings;
    1472  if (setting_iter) {
    1473  // gboolean found = FALSE;
    1474  while (setting_iter->type != REMMINA_PROTOCOL_SETTING_TYPE_END) {
    1475  if (setting_iter->name == NULL) {
    1476  g_error("Internal error: a setting name in protocol plugin %s is "
    1477  "null. Please fix RemminaProtocolSetting struct content.",
    1478  protocol_plugin->name);
    1479  } else if ((gchar *)setting_name_to_validate) {
    1480  if (strcmp((gchar *)setting_name_to_validate, setting_iter->name) == 0) {
    1481  // found = TRUE;
    1482 
    1483  gpointer validator_data = setting_iter->validator_data;
    1484  GCallback validator = setting_iter->validator;
    1485 
    1486  // Default behaviour is that everything is valid,
    1487  // except a validator is given and its returned GError is not NULL.
    1488  GError *err_ret = NULL;
    1489 
    1490  g_debug("Checking setting '%s' for validation.", setting_iter->name);
    1491  if (validator != NULL) {
    1492  // Looks weird but it calls the setting's validator
    1493  // function using setting_name_to_validate, value and
    1494  // validator_data as parameters and it returns a GError*.
    1495  err_ret = ((GError * (*)(gpointer, gconstpointer, gpointer)) validator)(setting_name_to_validate, value, validator_data);
    1496  }
    1497 
    1498  if (err_ret) {
    1499  g_debug("it has a validator function and it had an error!");
    1500  // pass err (returned value) to function caller.
    1501  *err = err_ret;
    1502  return FALSE;
    1503  }
    1504 
    1505  break;
    1506  }
    1507  }
    1508  setting_iter++;
    1509  }
    1510 
    1511  // if (!found) {
    1512  // TOO VERBOSE:
    1513  // g_warning("%s is not a plugin setting!", setting_name_to_validate);
    1514  // }
    1515  }
    1516 
    1517  return TRUE;
    1518 }
    1519 
    1521  GtkWidget ** failed_widget)
    1522 {
    1523  TRACE_CALL(__func__);
    1524  RemminaFileEditorPriv *priv = gfe->priv;
    1525  GHashTableIter iter;
    1526  gpointer key;
    1527  gpointer widget;
    1528  GtkTextBuffer *buffer;
    1529  gchar *escaped, *unescaped;
    1530  GtkTextIter start, end;
    1531 
    1532  GError *err = NULL;
    1533  *failed_widget = NULL;
    1534 
    1535  g_hash_table_iter_init(&iter, priv->setting_widgets);
    1536  while (g_hash_table_iter_next(&iter, &key, &widget)) {
    1537  // We don't want to save or validate grayed-out settings.
    1538  if (!gtk_widget_get_sensitive(GTK_WIDGET(widget))) {
    1539  g_debug("Grayed-out setting-widget '%s' will not be saved.",
    1540  gtk_widget_get_name(widget));
    1541  continue;
    1542  }
    1543 
    1544  if (GTK_IS_ENTRY(widget)) {
    1545  const gchar *value = gtk_entry_get_text(GTK_ENTRY(widget));
    1546 
    1547  if (!remmina_file_editor_validate_settings(gfe, (gchar *)key, value, &err)) {
    1548  // Error while validating!
    1549  // err should be set now.
    1550  *failed_widget = widget;
    1551  break;
    1552  }
    1553 
    1554  remmina_file_set_string(priv->remmina_file, (gchar *)key, value);
    1555  } else if (GTK_IS_TEXT_VIEW(widget)) {
    1556  buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget));
    1557  gtk_text_buffer_get_start_iter(buffer, &start);
    1558  gtk_text_buffer_get_end_iter(buffer, &end);
    1559  unescaped = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
    1560  escaped = g_uri_escape_string(unescaped, NULL, TRUE);
    1561 
    1562  if (!remmina_file_editor_validate_settings(gfe, (gchar *)key, escaped, &err)) {
    1563  // Error while validating!
    1564  // err should be set now.
    1565  *failed_widget = widget;
    1566  break;
    1567  }
    1568 
    1569  remmina_file_set_string(priv->remmina_file, (gchar *)key, escaped);
    1570  g_free(escaped);
    1571  } else if (GTK_IS_COMBO_BOX(widget)) {
    1572  gchar *value = remmina_public_combo_get_active_text(GTK_COMBO_BOX(widget));
    1573 
    1574  if (!remmina_file_editor_validate_settings(gfe, (gchar *)key, value, &err)) {
    1575  // Error while validating!
    1576  // err should be set now.
    1577  *failed_widget = widget;
    1578  break;
    1579  }
    1580 
    1581  remmina_file_set_string(priv->remmina_file, (gchar *)key, value);
    1582  } else if (GTK_IS_FILE_CHOOSER(widget)) {
    1583  gchar *value = gtk_widget_get_sensitive(GTK_WIDGET(widget)) ? gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget)) : NULL;
    1584 
    1585  if (!remmina_file_editor_validate_settings(gfe, (gchar *)key, value, &err)) {
    1586  // Error while validating!
    1587  // err should be set now.
    1588  g_free(value);
    1589  *failed_widget = widget;
    1590  break;
    1591  }
    1592 
    1593  remmina_file_set_string(priv->remmina_file, (gchar *)key, value);
    1594  g_free(value);
    1595  } else if (GTK_IS_TOGGLE_BUTTON(widget)) {
    1596  gboolean value = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget));
    1597 
    1598  if (!remmina_file_editor_validate_settings(gfe, (gchar *)key, &value, &err)) {
    1599  // Error while validating!
    1600  // err should be set now.
    1601  *failed_widget = widget;
    1602  break;
    1603  }
    1604 
    1605  remmina_file_set_int(priv->remmina_file, (gchar *)key, value);
    1606  }
    1607  }
    1608 
    1609  if (err) {
    1610  return err;
    1611  }
    1612 
    1613  return NULL;
    1614 }
    1615 
    1617  GtkWidget ** failed_widget)
    1618 {
    1619  TRACE_CALL(__func__);
    1620  int res_w, res_h;
    1621  gchar *custom_resolution;
    1623 
    1624  RemminaFileEditorPriv *priv = gfe->priv;
    1625 
    1626  remmina_file_set_string(priv->remmina_file, "name", gtk_entry_get_text(GTK_ENTRY(priv->name_entry)));
    1627 
    1628  remmina_file_set_string(priv->remmina_file, "labels", gtk_entry_get_text(GTK_ENTRY(priv->labels_entry)));
    1629 
    1630  remmina_file_set_string(priv->remmina_file, "group",
    1631  (priv->group_combo ? remmina_public_combo_get_active_text(GTK_COMBO_BOX(priv->group_combo)) : NULL));
    1632 
    1633  remmina_file_set_string(priv->remmina_file, "protocol",
    1634  remmina_public_combo_get_active_text(GTK_COMBO_BOX(priv->protocol_combo)));
    1635 
    1636  remmina_file_set_string(priv->remmina_file, "server",
    1637  (priv->server_combo ? remmina_public_combo_get_active_text(GTK_COMBO_BOX(priv->server_combo)) : NULL));
    1638 
    1639  if (priv->resolution_auto_radio) {
    1640  if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->resolution_auto_radio))) {
    1641  /* Resolution is set to auto (which means: Use client fullscreen resolution, aka use client resolution) */
    1642  res_w = res_h = 0;
    1643  res_mode = RES_USE_CLIENT;
    1644  } else if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(priv->resolution_iws_radio))) {
    1645  /* Resolution is set to initial window size */
    1646  res_w = res_h = 0;
    1647  res_mode = RES_USE_INITIAL_WINDOW_SIZE;
    1648  } else {
    1649  /* Resolution is set to a value from the list */
    1650  custom_resolution = remmina_public_combo_get_active_text(GTK_COMBO_BOX(priv->resolution_custom_combo));
    1651  if (remmina_public_split_resolution_string(custom_resolution, &res_w, &res_h))
    1652  res_mode = RES_USE_CUSTOM;
    1653  else
    1654  res_mode = RES_USE_INITIAL_WINDOW_SIZE;
    1655  g_free(custom_resolution);
    1656  }
    1657  remmina_file_set_int(priv->remmina_file, "resolution_mode", res_mode);
    1658  remmina_file_set_int(priv->remmina_file, "resolution_width", res_w);
    1659  remmina_file_set_int(priv->remmina_file, "resolution_height", res_h);
    1660  }
    1661 
    1662  if (priv->keymap_combo)
    1663  remmina_file_set_string(priv->remmina_file, "keymap",
    1664  remmina_public_combo_get_active_text(GTK_COMBO_BOX(priv->keymap_combo)));
    1665 
    1668  return remmina_file_editor_update_settings(gfe, failed_widget);
    1669 }
    1670 
    1671 static void remmina_file_editor_on_default(GtkWidget *button, RemminaFileEditor *gfe)
    1672 {
    1673  TRACE_CALL(__func__);
    1674  RemminaFile *gf;
    1675  GtkWidget *dialog;
    1676 
    1677  GtkWidget *failed_widget = NULL;
    1678  GError *err = remmina_file_editor_update(gfe, &failed_widget);
    1679  if (err) {
    1680  g_warning(_("Couldn't validate user input. %s"), err->message);
    1681  remmina_file_editor_show_validation_error_popup(gfe, failed_widget, err);
    1682  return;
    1683  }
    1684 
    1685  gf = remmina_file_dup(gfe->priv->remmina_file);
    1686 
    1688 
    1689  /* Clear properties that should never be default */
    1690  remmina_file_set_string(gf, "name", NULL);
    1691  remmina_file_set_string(gf, "server", NULL);
    1692  remmina_file_set_string(gf, "password", NULL);
    1693  remmina_file_set_string(gf, "precommand", NULL);
    1694  remmina_file_set_string(gf, "postcommand", NULL);
    1695 
    1696  remmina_file_set_string(gf, "ssh_tunnel_server", NULL);
    1697  remmina_file_set_string(gf, "ssh_tunnel_password", NULL);
    1698  remmina_file_set_string(gf, "ssh_tunnel_passphrase", NULL);
    1699 
    1700  remmina_file_save(gf);
    1701  remmina_file_free(gf);
    1702 
    1703  dialog = gtk_message_dialog_new(GTK_WINDOW(gfe), GTK_DIALOG_MODAL, GTK_MESSAGE_INFO,
    1704  GTK_BUTTONS_OK, _("Default settings saved."));
    1705  gtk_dialog_run(GTK_DIALOG(dialog));
    1706  gtk_widget_destroy(dialog);
    1707 }
    1708 
    1709 static void remmina_file_editor_on_save(GtkWidget *button, RemminaFileEditor *gfe)
    1710 {
    1711  TRACE_CALL(__func__);
    1712 
    1713  GtkWidget *failed_widget = NULL;
    1714  GError *err = remmina_file_editor_update(gfe, &failed_widget);
    1715  if (err) {
    1716  g_warning(_("Couldn't validate user input. %s"), err->message);
    1717  remmina_file_editor_show_validation_error_popup(gfe, failed_widget, err);
    1718  return;
    1719  }
    1720 
    1722 
    1723  remmina_file_save(gfe->priv->remmina_file);
    1725 
    1726  gtk_widget_destroy(GTK_WIDGET(gfe));
    1727 }
    1728 
    1729 static void remmina_file_editor_on_connect(GtkWidget *button, RemminaFileEditor *gfe)
    1730 {
    1731  TRACE_CALL(__func__);
    1732  RemminaFile *gf;
    1733 
    1734  GtkWidget *failed_widget = NULL;
    1735  GError *err = remmina_file_editor_update(gfe, &failed_widget);
    1736  if (err) {
    1737  g_warning(_("Couldn't validate user input. %s"), err->message);
    1738  remmina_file_editor_show_validation_error_popup(gfe, failed_widget, err);
    1739  return;
    1740  }
    1741 
    1742  gf = remmina_file_dup(gfe->priv->remmina_file);
    1743  /* Put server into name for "Quick Connect" */
    1744  if (remmina_file_get_filename(gf) == NULL)
    1745  remmina_file_set_string(gf, "name", remmina_file_get_string(gf, "server"));
    1746  gtk_widget_destroy(GTK_WIDGET(gfe));
    1747  gf->prevent_saving = TRUE;
    1748  rcw_open_from_file(gf);
    1749 }
    1750 
    1751 static void remmina_file_editor_on_save_connect(GtkWidget *button, RemminaFileEditor *gfe)
    1752 {
    1753  TRACE_CALL(__func__);
    1755  RemminaFile *gf;
    1756 
    1757  GtkWidget *failed_widget = NULL;
    1758  GError *err = remmina_file_editor_update(gfe, &failed_widget);
    1759  if (err) {
    1760  g_warning(_("Couldn't validate user input. %s"), err->message);
    1761  remmina_file_editor_show_validation_error_popup(gfe, failed_widget, err);
    1762  return;
    1763  }
    1764 
    1766 
    1767  remmina_file_save(gfe->priv->remmina_file);
    1769 
    1770  gf = remmina_file_dup(gfe->priv->remmina_file);
    1771  /* Put server into name for Quick Connect */
    1772  if (remmina_file_get_filename(gf) == NULL)
    1773  remmina_file_set_string(gf, "name", remmina_file_get_string(gf, "server"));
    1774  gtk_widget_destroy(GTK_WIDGET(gfe));
    1775  rcw_open_from_file(gf);
    1776 }
    1777 
    1778 static void remmina_file_editor_on_cancel(GtkWidget *button, RemminaFileEditor *gfe)
    1779 {
    1780  TRACE_CALL(__func__);
    1781  gtk_widget_destroy(GTK_WIDGET(gfe));
    1782 }
    1783 
    1785 {
    1786  TRACE_CALL(__func__);
    1787  RemminaFileEditorPriv *priv;
    1788  GtkWidget *widget;
    1789 
    1790  priv = g_new0(RemminaFileEditorPriv, 1);
    1791  gfe->priv = priv;
    1792 
    1793  /* Create the editor dialog */
    1794  gtk_window_set_title(GTK_WINDOW(gfe), _("Remote Connection Profile"));
    1795 
    1796  widget = gtk_dialog_add_button(GTK_DIALOG(gfe), (_("_Cancel")), GTK_RESPONSE_CANCEL);
    1797  g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_file_editor_on_cancel), gfe);
    1798 
    1799  /* Default button */
    1800  widget = gtk_dialog_add_button(GTK_DIALOG(gfe), (_("Save as Default")), GTK_RESPONSE_OK);
    1801  gtk_widget_set_tooltip_text(GTK_WIDGET(widget), _("Use the current settings as the default for all new connection profiles"));
    1802  g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_file_editor_on_default), gfe);
    1803 
    1804  widget = gtk_dialog_add_button(GTK_DIALOG(gfe), (_("_Save")), GTK_RESPONSE_APPLY);
    1805  g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_file_editor_on_save), gfe);
    1806  gtk_widget_set_sensitive(widget, FALSE);
    1807  priv->save_button = widget;
    1808 
    1809  widget = gtk_dialog_add_button(GTK_DIALOG(gfe), (_("Connect")), GTK_RESPONSE_ACCEPT);
    1810  g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_file_editor_on_connect), gfe);
    1811 
    1812  widget = gtk_dialog_add_button(GTK_DIALOG(gfe), (_("_Save and Connect")), GTK_RESPONSE_OK);
    1813  gtk_widget_set_can_default(widget, TRUE);
    1814  g_signal_connect(G_OBJECT(widget), "clicked", G_CALLBACK(remmina_file_editor_on_save_connect), gfe);
    1815 
    1816  gtk_dialog_set_default_response(GTK_DIALOG(gfe), GTK_RESPONSE_OK);
    1817  gtk_window_set_default_size(GTK_WINDOW(gfe), 800, 600);
    1818 
    1819  g_signal_connect(G_OBJECT(gfe), "destroy", G_CALLBACK(remmina_file_editor_destroy), NULL);
    1820  g_signal_connect(G_OBJECT(gfe), "realize", G_CALLBACK(remmina_file_editor_on_realize), NULL);
    1821 
    1822  priv->setting_widgets = g_hash_table_new(g_str_hash, g_str_equal);
    1823 
    1824  remmina_widget_pool_register(GTK_WIDGET(gfe));
    1825 }
    1826 
    1827 static gboolean remmina_file_editor_iterate_protocol(gchar *protocol, RemminaPlugin *plugin, gpointer data)
    1828 {
    1829  TRACE_CALL(__func__);
    1830  RemminaFileEditor *gfe = REMMINA_FILE_EDITOR(data);
    1831  GtkListStore *store;
    1832  GtkTreeIter iter;
    1833  gboolean first;
    1834 
    1835  store = GTK_LIST_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(gfe->priv->protocol_combo)));
    1836 
    1837  first = !gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter);
    1838 
    1839  gtk_list_store_append(store, &iter);
    1840  gtk_list_store_set(store, &iter, 0, protocol, 1, g_dgettext(plugin->domain, plugin->description), 2,
    1841  ((RemminaProtocolPlugin *)plugin)->icon_name, -1);
    1842 
    1843  if (first || g_strcmp0(protocol, remmina_file_get_string(gfe->priv->remmina_file, "protocol")) == 0)
    1844  gtk_combo_box_set_active_iter(GTK_COMBO_BOX(gfe->priv->protocol_combo), &iter);
    1845 
    1846  return FALSE;
    1847 }
    1848 
    1850 {
    1851  TRACE_CALL(__func__);
    1852  RemminaFileEditorPriv *priv;
    1853 
    1854  priv = gfe->priv;
    1855  gtk_widget_set_sensitive(priv->group_combo, TRUE);
    1856  gtk_widget_set_sensitive(priv->save_button, TRUE);
    1857 }
    1858 
    1859 static void remmina_file_editor_entry_on_changed(GtkEditable *editable, RemminaFileEditor *gfe)
    1860 {
    1861  TRACE_CALL(__func__);
    1862  RemminaFileEditorPriv *priv;
    1863 
    1864  priv = gfe->priv;
    1865  if (remmina_file_get_filename(priv->remmina_file) == NULL) {
    1866  remmina_file_generate_filename(priv->remmina_file);
    1867  /* TODO: Probably to be removed */
    1869  } else {
    1870  remmina_file_delete(remmina_file_get_filename(priv->remmina_file));
    1871  remmina_file_generate_filename(priv->remmina_file);
    1873  }
    1874 }
    1875 
    1877 {
    1878  TRACE_CALL(__func__);
    1879  RemminaFileEditorPriv *priv;
    1880 
    1881  priv = gfe->priv;
    1882  if (remmina_file_get_filename(priv->remmina_file) == NULL) {
    1883  remmina_file_generate_filename(priv->remmina_file);
    1884  } else {
    1885  remmina_file_delete(remmina_file_get_filename(priv->remmina_file));
    1886  remmina_file_generate_filename(priv->remmina_file);
    1887  }
    1888 }
    1889 
    1891 {
    1892  TRACE_CALL(__func__);
    1893  RemminaFileEditor *gfe;
    1894  RemminaFileEditorPriv *priv;
    1895  GtkWidget *grid;
    1896  GtkWidget *widget;
    1897  gchar *groups;
    1898  gchar *s;
    1899  const gchar *cs;
    1900 
    1901  gfe = REMMINA_FILE_EDITOR(g_object_new(REMMINA_TYPE_FILE_EDITOR, NULL));
    1902  priv = gfe->priv;
    1903  priv->remmina_file = remminafile;
    1904 
    1905  if (remmina_file_get_filename(remminafile) == NULL)
    1906  gtk_dialog_set_response_sensitive(GTK_DIALOG(gfe), GTK_RESPONSE_APPLY, FALSE);
    1907 
    1908  /* Create the "Profile" group on the top (for name and protocol) */
    1909  grid = gtk_grid_new();
    1910  gtk_widget_show(grid);
    1911  gtk_grid_set_row_spacing(GTK_GRID(grid), 4);
    1912  gtk_grid_set_column_spacing(GTK_GRID(grid), 8);
    1913  gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE);
    1914  gtk_container_set_border_width(GTK_CONTAINER(grid), 8);
    1915  gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(gfe))), grid, FALSE, FALSE, 2);
    1916 
    1917  // remmina_public_create_group(GTK_GRID(grid), _("Profile"), 0, 4, 3);
    1918 
    1919  gboolean profile_file_exists = (remmina_file_get_filename(remminafile) != NULL);
    1920 
    1921  /* Profile: Name */
    1922  widget = gtk_label_new(_("Name"));
    1923  gtk_widget_show(widget);
    1924  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    1925  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    1926  gtk_grid_attach(GTK_GRID(grid), widget, 0, 3, 2, 1);
    1927  gtk_grid_set_column_spacing(GTK_GRID(grid), 10);
    1928 
    1929  widget = gtk_entry_new();
    1930  gtk_widget_show(widget);
    1931  gtk_grid_attach(GTK_GRID(grid), widget, 1, 3, 3, 1);
    1932  gtk_entry_set_max_length(GTK_ENTRY(widget), 100);
    1933  priv->name_entry = widget;
    1934 
    1935  if (!profile_file_exists) {
    1936  gtk_entry_set_text(GTK_ENTRY(widget), _("Quick Connect"));
    1937 #if GTK_CHECK_VERSION(3, 16, 0)
    1938  gtk_entry_grab_focus_without_selecting(GTK_ENTRY(widget));
    1939 #endif
    1940  g_signal_connect(G_OBJECT(widget), "changed", G_CALLBACK(remmina_file_editor_entry_on_changed), gfe);
    1941  } else {
    1942  cs = remmina_file_get_string(remminafile, "name");
    1943  gtk_entry_set_text(GTK_ENTRY(widget), cs ? cs : "");
    1944  }
    1945 
    1946  /* Profile: Group */
    1947  widget = gtk_label_new(_("Group"));
    1948  gtk_widget_show(widget);
    1949  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    1950  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    1951  gtk_grid_attach(GTK_GRID(grid), widget, 0, 6, 2, 1);
    1952 
    1954  priv->group_combo = remmina_public_create_combo_entry(groups, remmina_file_get_string(remminafile, "group"), FALSE);
    1955  g_free(groups);
    1956  gtk_widget_show(priv->group_combo);
    1957  gtk_grid_attach(GTK_GRID(grid), priv->group_combo, 1, 6, 3, 1);
    1958  gtk_widget_set_sensitive(priv->group_combo, FALSE);
    1959 
    1960  s = g_strdup_printf(_("Use '%s' as subgroup delimiter"), "/");
    1961  gtk_widget_set_tooltip_text(priv->group_combo, s);
    1962  g_free(s);
    1963 
    1964  /* Profile: Labels */
    1965  widget = gtk_label_new(_("Labels"));
    1966  gtk_widget_show(widget);
    1967  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    1968  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    1969  gtk_grid_attach(GTK_GRID(grid), widget, 0, 9, 2, 1);
    1970  gtk_grid_set_column_spacing(GTK_GRID(grid), 10);
    1971 
    1972  widget = gtk_entry_new();
    1973  gtk_widget_show(widget);
    1974  gtk_grid_attach(GTK_GRID(grid), widget, 1, 9, 3, 1);
    1975  gtk_entry_set_max_length(GTK_ENTRY(widget), 255);
    1976  priv->labels_entry = widget;
    1977 
    1978  if (!profile_file_exists) {
    1979  gtk_widget_set_tooltip_text(widget, _("Label1,Label2"));
    1980 #if GTK_CHECK_VERSION(3, 16, 0)
    1981  gtk_entry_grab_focus_without_selecting(GTK_ENTRY(widget));
    1982 #endif
    1983  g_signal_connect(G_OBJECT(widget), "changed", G_CALLBACK(remmina_file_editor_entry_on_changed), gfe);
    1984  } else {
    1985  cs = remmina_file_get_string(remminafile, "labels");
    1986  gtk_entry_set_text(GTK_ENTRY(widget), cs ? cs : "");
    1987  }
    1988 
    1989  /* Profile: Protocol */
    1990  widget = gtk_label_new(_("Protocol"));
    1991  gtk_widget_show(widget);
    1992  gtk_widget_set_valign(widget, GTK_ALIGN_START);
    1993  gtk_widget_set_halign(widget, GTK_ALIGN_START);
    1994  gtk_grid_attach(GTK_GRID(grid), widget, 0, 12, 2, 1);
    1995 
    1996  widget = remmina_public_create_combo(TRUE);
    1997  gtk_widget_show(widget);
    1998  gtk_grid_attach(GTK_GRID(grid), widget, 1, 12, 3, 1);
    1999  priv->protocol_combo = widget;
    2001  g_signal_connect(G_OBJECT(widget), "changed", G_CALLBACK(remmina_file_editor_protocol_combo_on_changed), gfe);
    2002 
    2003  /* Create the "Preference" frame */
    2004  widget = gtk_event_box_new();
    2005  gtk_widget_show(widget);
    2006  gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(gfe))), widget, TRUE, TRUE, 2);
    2007  priv->config_box = widget;
    2008 
    2009  priv->config_container = NULL;
    2010  priv->config_scrollable = NULL;
    2011 
    2012  remmina_file_editor_protocol_combo_on_changed(GTK_COMBO_BOX(priv->protocol_combo), gfe);
    2013 
    2015 
    2016  return GTK_WIDGET(gfe);
    2017 }
    2018 
    2019 GtkWidget *remmina_file_editor_new(void)
    2020 {
    2021  TRACE_CALL(__func__);
    2022  return remmina_file_editor_new_full(NULL, NULL);
    2023 }
    2024 
    2025 GtkWidget *remmina_file_editor_new_full(const gchar *server, const gchar *protocol)
    2026 {
    2027  TRACE_CALL(__func__);
    2028  RemminaFile *remminafile;
    2029 
    2030  remminafile = remmina_file_new();
    2031  if (server)
    2032  remmina_file_set_string(remminafile, "server", server);
    2033  if (protocol)
    2034  remmina_file_set_string(remminafile, "protocol", protocol);
    2035 
    2036  return remmina_file_editor_new_from_file(remminafile);
    2037 }
    2038 
    2039 GtkWidget *remmina_file_editor_new_copy(const gchar *filename)
    2040 {
    2041  TRACE_CALL(__func__);
    2042  RemminaFile *remminafile;
    2043  GtkWidget *dialog;
    2044 
    2045  remminafile = remmina_file_copy(filename);
    2046 
    2047  if (remminafile) {
    2048  return remmina_file_editor_new_from_file(remminafile);
    2049  } else {
    2050  dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
    2051  _("Could not find the file “%s”."), filename);
    2052  gtk_dialog_run(GTK_DIALOG(dialog));
    2053  gtk_widget_destroy(dialog);
    2054  return NULL;
    2055  }
    2056 }
    2057 
    2058 GtkWidget *remmina_file_editor_new_from_filename(const gchar *filename)
    2059 {
    2060  TRACE_CALL(__func__);
    2061  RemminaFile *remminafile;
    2062 
    2063  remminafile = remmina_file_manager_load_file(filename);
    2064  if (remminafile) {
    2065  if (remmina_file_get_int(remminafile, "profile-lock", FALSE) && remmina_unlock_new(remmina_main_get_window()) == 0)
    2066  return NULL;
    2067  return remmina_file_editor_new_from_file(remminafile);
    2068  } else {
    2069  GtkWidget *dialog = gtk_message_dialog_new(NULL, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_CLOSE,
    2070  _("Could not find the file “%s”."), filename);
    2071  gtk_dialog_run(GTK_DIALOG(dialog));
    2072  gtk_widget_destroy(dialog);
    2073  return NULL;
    2074  }
    2075 }
    void remmina_public_create_group(GtkGrid *grid, const gchar *group, gint row, gint rows, gint cols)
    const gchar * remmina_plugin_manager_get_canonical_setting_name(const RemminaProtocolSetting *setting)
    GtkDialog * remmina_string_list_new(gboolean two_columns, const gchar *fields_separator)
    @@ -95,30 +95,30 @@ $(document).ready(function(){initNavTree('remmina__file__editor_8c_source.html',
    const gchar * remmina_file_get_string(RemminaFile *remminafile, const gchar *setting)
    Definition: remmina_file.c:516
    gchar ** remmina_pref_keymap_groups(void)
    -
    static void remmina_file_editor_create_resolution(RemminaFileEditor *gfe, const RemminaProtocolSetting *setting, GtkWidget *grid, gint row)
    +
    static void remmina_file_editor_create_resolution(RemminaFileEditor *gfe, const RemminaProtocolSetting *setting, GtkWidget *grid, gint row)
    -
    static GtkWidget * remmina_file_editor_create_combo(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gchar *list, const gchar *value, gchar *setting_name)
    +
    static GtkWidget * remmina_file_editor_create_combo(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gchar *list, const gchar *value, gchar *setting_name)
    RemminaFile * remmina_file_dup(RemminaFile *remminafile)
    Definition: remmina_file.c:865
    GtkWidget * remmina_public_create_combo_entry(const gchar *text, const gchar *def, gboolean descending)
    -
    static void remmina_file_editor_on_connect(GtkWidget *button, RemminaFileEditor *gfe)
    +
    static void remmina_file_editor_on_connect(GtkWidget *button, RemminaFileEditor *gfe)
    gchar * remmina_pref_file
    Definition: rcw.c:78
    -
    GtkWindow * remmina_main_get_window()
    +
    GtkWindow * remmina_main_get_window()
    void remmina_string_list_set_validation_func(RemminaStringListValidationFunc func)
    G_DEFINE_TYPE(RemminaFileEditor, remmina_file_editor, GTK_TYPE_DIALOG)
    -
    static GtkWidget * remmina_file_editor_create_int(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gint value, gint left, gint right, gchar *setting_name)
    +
    static GtkWidget * remmina_file_editor_create_int(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gint value, gint left, gint right, gchar *setting_name)
    static void remmina_file_editor_ssh_tunnel_enabled_check_on_toggled(GtkToggleButton *togglebutton, RemminaFileEditor *gfe, RemminaProtocolSSHSetting ssh_setting)
    const gchar * remmina_file_get_filename(RemminaFile *remminafile)
    Definition: remmina_file.c:210
    -
    static GtkWidget * remmina_file_editor_create_double(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, gdouble value, gint left, gint right, gchar *setting_name)
    -
    static GtkWidget * remmina_file_editor_create_select(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gpointer *list, const gchar *value, gchar *setting_name)
    +
    static GtkWidget * remmina_file_editor_create_double(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, gdouble value, gint left, gint right, gchar *setting_name)
    +
    static GtkWidget * remmina_file_editor_create_select(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gpointer *list, const gchar *value, gchar *setting_name)
    typedefG_BEGIN_DECLS struct _RemminaFile RemminaFile
    Definition: types.h:44
    -
    static void remmina_file_editor_protocol_combo_on_changed(GtkComboBox *combo, RemminaFileEditor *gfe)
    +
    static void remmina_file_editor_protocol_combo_on_changed(GtkComboBox *combo, RemminaFileEditor *gfe)
    void remmina_plugin_manager_for_each_plugin(RemminaPluginType type, RemminaPluginFunc func, gpointer data)
    void remmina_widget_pool_register(GtkWidget *widget)
    @@ -131,12 +131,11 @@ $(document).ready(function(){initNavTree('remmina__file__editor_8c_source.html',
    const gchar * domain
    Definition: plugin.h:60
    gchar * remmina_pref_get_recent(const gchar *protocol)
    Definition: remmina_pref.c:967
    -
    static void remmina_file_toggle_password_view(GtkWidget *widget, gpointer data)
    static void remmina_file_editor_create_server(RemminaFileEditor *gfe, const RemminaProtocolSetting *setting, GtkWidget *grid, gint row)
    void remmina_icon_populate_menu(void)
    Definition: remmina_icon.c:250
    -
    GtkWidget * remmina_file_editor_new_full(const gchar *server, const gchar *protocol)
    -
    static void remmina_file_editor_init(RemminaFileEditor *gfe)
    +
    GtkWidget * remmina_file_editor_new_full(const gchar *server, const gchar *protocol)
    +
    static void remmina_file_editor_init(RemminaFileEditor *gfe)
    gchar * resolutions
    Definition: remmina_pref.h:145
    gdouble remmina_file_get_double(RemminaFile *remminafile, const gchar *setting, gfloat default_value)
    void remmina_file_generate_filename(RemminaFile *remminafile)
    Generate a new Remmina connection profile file name.
    Definition: remmina_file.c:114
    @@ -149,17 +148,17 @@ $(document).ready(function(){initNavTree('remmina__file__editor_8c_source.html',
    RemminaProtocolWidgetResolutionMode
    Definition: types.h:147
    static void remmina_file_editor_show_validation_error_popup(RemminaFileEditor *gfe, GtkWidget *failed_widget, GError *err)
    Shows a tooltip-like window which tells the user what they did wrong to trigger the validation functi...
    GtkWidget * remmina_public_create_combo_map(const gpointer *key_value_list, const gchar *def, gboolean use_icon, const gchar *domain)
    -
    static GtkWidget * remmina_file_editor_create_chooser(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gchar *value, gint type, gchar *setting_name)
    Create checkbox + gtk_file_chooser for open files and select folders.
    +
    static GtkWidget * remmina_file_editor_create_chooser(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gchar *value, gint type, gchar *setting_name)
    Create checkbox + gtk_file_chooser for open files and select folders.
    -
    static GtkWidget * remmina_file_editor_create_password(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gchar *value, gchar *setting_name)
    +
    static GtkWidget * remmina_file_editor_create_password(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gchar *value, gchar *setting_name)
    void remmina_file_set_filename(RemminaFile *remminafile, const gchar *filename)
    Definition: remmina_file.c:182
    -
    static gpointer ssh_tunnel_auth_list[]
    +
    static gpointer ssh_tunnel_auth_list[]
    -
    static GError * remmina_file_editor_update_settings(RemminaFileEditor *gfe, GtkWidget **failed_widget)
    +
    static GError * remmina_file_editor_update_settings(RemminaFileEditor *gfe, GtkWidget **failed_widget)
    -
    void remmina_file_editor_check_profile(RemminaFileEditor *gfe)
    +
    void remmina_file_editor_check_profile(RemminaFileEditor *gfe)
    GtkWidget * remmina_public_create_combo_text_d(const gchar *text, const gchar *def, const gchar *empty_choice)
    struct _RemminaFileEditorPriv RemminaFileEditorPriv
    static GtkWidget * remmina_file_editor_create_notebook_tab(RemminaFileEditor *gfe, const gchar *stock_id, const gchar *label, gint rows, gint cols)
    @@ -170,25 +169,24 @@ $(document).ready(function(){initNavTree('remmina__file__editor_8c_source.html',
    void remmina_file_set_int(RemminaFile *remminafile, const gchar *setting, gint value)
    Definition: remmina_file.c:585
    void remmina_file_delete(const gchar *filename)
    Definition: remmina_file.c:911
    -
    static void remmina_file_editor_entry_on_changed(GtkEditable *editable, RemminaFileEditor *gfe)
    -
    static GtkWidget * remmina_file_editor_create_text2(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gchar *value, gint left, gint right, gchar *setting_name)
    +
    static void remmina_file_editor_entry_on_changed(GtkEditable *editable, RemminaFileEditor *gfe)
    +
    static GtkWidget * remmina_file_editor_create_text2(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gchar *value, gint left, gint right, gchar *setting_name)
    const RemminaProtocolSetting * basic_settings
    Definition: plugin.h:74
    -
    static GtkWidget * remmina_file_editor_create_check(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint top, const gchar *label, gboolean value, gchar *setting_name)
    -
    static void remmina_file_editor_create_all_settings(RemminaFileEditor *gfe)
    +
    static GtkWidget * remmina_file_editor_create_check(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint top, const gchar *label, gboolean value, gchar *setting_name)
    +
    static void remmina_file_editor_create_all_settings(RemminaFileEditor *gfe)
    static void remmina_file_editor_create_notebook_container(RemminaFileEditor *gfe)
    -
    GtkWidget * remmina_file_editor_new_from_file(RemminaFile *remminafile)
    +
    GtkWidget * remmina_file_editor_new_from_file(RemminaFile *remminafile)
    gpointer validator_data
    Definition: types.h:123
    -
    gboolean remmina_pref_get_boolean(const gchar *key)
    -
    void remmina_file_editor_int_setting_filter(GtkEditable *editable, const gchar *text, gint length, gint *position, gpointer data)
    +
    void remmina_file_editor_int_setting_filter(GtkEditable *editable, const gchar *text, gint length, gint *position, gpointer data)
    void remmina_string_list_set_text(const gchar *text, const gboolean clear_data)
    -
    GtkWidget * remmina_file_editor_new_from_filename(const gchar *filename)
    +
    GtkWidget * remmina_file_editor_new_from_filename(const gchar *filename)
    -
    static void remmina_file_editor_create_ssh_tunnel_tab(RemminaFileEditor *gfe, RemminaProtocolSSHSetting ssh_setting)
    +
    static void remmina_file_editor_create_ssh_tunnel_tab(RemminaFileEditor *gfe, RemminaProtocolSSHSetting ssh_setting)
    RemminaProtocolSettingType type
    Definition: types.h:117
    @@ -197,55 +195,56 @@ $(document).ready(function(){initNavTree('remmina__file__editor_8c_source.html',
    RemminaFile * remmina_file_new(void)
    Definition: remmina_file.c:93
    void remmina_string_list_set_titles(gchar *title1, gchar *title2)
    GCallback validator
    Definition: types.h:124
    -
    static void remmina_file_editor_create_settings(RemminaFileEditor *gfe, GtkWidget *grid, const RemminaProtocolSetting *settings)
    -
    static void remmina_file_editor_on_save_connect(GtkWidget *button, RemminaFileEditor *gfe)
    +
    static void remmina_file_editor_create_settings(RemminaFileEditor *gfe, GtkWidget *grid, const RemminaProtocolSetting *settings)
    +
    static void remmina_file_editor_on_save_connect(GtkWidget *button, RemminaFileEditor *gfe)
    void rcw_open_from_file(RemminaFile *remminafile)
    Definition: rcw.c:4446
    RemminaPref remmina_pref
    Definition: rcw.c:79
    -
    void remmina_file_editor_file_save(RemminaFileEditor *gfe)
    +
    void remmina_file_editor_file_save(RemminaFileEditor *gfe)
    gint remmina_file_get_int(RemminaFile *remminafile, const gchar *setting, gint default_value)
    Definition: remmina_file.c:603
    -
    GtkWidget * remmina_file_editor_new(void)
    +
    GtkWidget * remmina_file_editor_new(void)
    static void remmina_file_editor_on_realize(GtkWidget *widget, gpointer user_data)
    static void remmina_file_editor_button_on_toggled(GtkToggleButton *togglebutton, GtkWidget *widget)
    -
    static void remmina_file_editor_on_cancel(GtkWidget *button, RemminaFileEditor *gfe)
    +
    static void remmina_file_editor_on_cancel(GtkWidget *button, RemminaFileEditor *gfe)
    RemminaPlugin * remmina_plugin_manager_get_plugin(RemminaPluginType type, const gchar *name)
    -
    static void remmina_file_editor_on_save(GtkWidget *button, RemminaFileEditor *gfe)
    -
    static void remmina_file_editor_on_default(GtkWidget *button, RemminaFileEditor *gfe)
    +
    static void remmina_file_editor_on_save(GtkWidget *button, RemminaFileEditor *gfe)
    +
    static void remmina_file_editor_on_default(GtkWidget *button, RemminaFileEditor *gfe)
    const gchar * name
    Definition: plugin.h:67
    -
    void remmina_file_editor_double_setting_filter(GtkEditable *editable, const gchar *text, gint length, gint *position, gpointer data)
    +
    void remmina_main_toggle_password_view(GtkWidget *widget, gpointer data)
    +
    void remmina_file_editor_double_setting_filter(GtkEditable *editable, const gchar *text, gint length, gint *position, gpointer data)
    gchar * remmina_file_manager_get_groups(void)
    -
    static GtkWidget * remmina_file_editor_create_text(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gchar *value, gchar *setting_name)
    +
    static GtkWidget * remmina_file_editor_create_text(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gchar *value, gchar *setting_name)
    void remmina_file_set_string(RemminaFile *remminafile, const gchar *setting, const gchar *value)
    Definition: remmina_file.c:469
    -
    static void remmina_file_editor_save_behavior_tab(RemminaFileEditor *gfe)
    -
    static void remmina_file_editor_create_behavior_tab(RemminaFileEditor *gfe)
    +
    static void remmina_file_editor_save_behavior_tab(RemminaFileEditor *gfe)
    +
    static void remmina_file_editor_create_behavior_tab(RemminaFileEditor *gfe)
    void remmina_file_save(RemminaFile *remminafile)
    Definition: remmina_file.c:730
    -
    static void remmina_file_editor_browse_resolution(GtkWidget *button, RemminaFileEditor *gfe)
    -
    static gboolean remmina_file_editor_validate_settings(RemminaFileEditor *gfe, gchar *setting_name_to_validate, gconstpointer value, GError **err)
    +
    static void remmina_file_editor_browse_resolution(GtkWidget *button, RemminaFileEditor *gfe)
    +
    static gboolean remmina_file_editor_validate_settings(RemminaFileEditor *gfe, gchar *setting_name_to_validate, gconstpointer value, GError **err)
    static void remmina_file_editor_ssh_tunnel_server_custom_radio_on_toggled(GtkToggleButton *togglebutton, RemminaFileEditor *gfe)
    RemminaFile * remmina_file_copy(const gchar *filename)
    Definition: remmina_file.c:217
    RemminaFile * remmina_file_manager_load_file(const gchar *filename)
    -
    static gboolean remmina_file_editor_iterate_protocol(gchar *protocol, RemminaPlugin *plugin, gpointer data)
    -
    static GError * remmina_file_editor_update(RemminaFileEditor *gfe, GtkWidget **failed_widget)
    +
    static gboolean remmina_file_editor_iterate_protocol(gchar *protocol, RemminaPlugin *plugin, gpointer data)
    +
    static GError * remmina_file_editor_update(RemminaFileEditor *gfe, GtkWidget **failed_widget)
    -
    GtkWidget * remmina_file_editor_new_copy(const gchar *filename)
    +
    GtkWidget * remmina_file_editor_new_copy(const gchar *filename)
    RemminaFileEditorPriv * priv
    -
    static GtkWidget * remmina_file_editor_create_textarea(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gchar *value, gchar *setting_name)
    +
    static GtkWidget * remmina_file_editor_create_textarea(RemminaFileEditor *gfe, GtkWidget *grid, gint row, gint col, const gchar *label, const gchar *value, gchar *setting_name)
    static void remmina_file_editor_browse_avahi(GtkWidget *button, RemminaFileEditor *gfe)
    gint remmina_unlock_new(GtkWindow *parent)
    void remmina_public_load_combo_text_d(GtkWidget *combo, const gchar *text, const gchar *def, const gchar *empty_choice)
    -
    static void remmina_file_editor_update_resolution(GtkWidget *widget, RemminaFileEditor *gfe)
    +
    static void remmina_file_editor_update_resolution(GtkWidget *widget, RemminaFileEditor *gfe)
    N_("Unable to connect to VNC server")
    Definition: vnc_plugin.c:953
    static void remmina_file_editor_class_init(RemminaFileEditorClass *klass)
    const gchar * label
    Definition: types.h:119
    -
    static void remmina_file_editor_save_ssh_tunnel_tab(RemminaFileEditor *gfe)
    +
    static void remmina_file_editor_save_ssh_tunnel_tab(RemminaFileEditor *gfe)
    gchar * remmina_string_list_get_text(void)
    const gchar * name
    Definition: types.h:118
    diff --git a/public/remmina__file__editor_8h.html b/public/remmina__file__editor_8h.html index 59b63986c..d2b18367f 100644 --- a/public/remmina__file__editor_8h.html +++ b/public/remmina__file__editor_8h.html @@ -190,7 +190,7 @@ Functions
    -

    Definition at line 1864 of file remmina_file_editor.c.

    +

    Definition at line 1849 of file remmina_file_editor.c.

    @@ -210,7 +210,7 @@ Functions
    -

    Definition at line 1891 of file remmina_file_editor.c.

    +

    Definition at line 1876 of file remmina_file_editor.c.

    @@ -248,7 +248,7 @@ Functions
    -

    Definition at line 2034 of file remmina_file_editor.c.

    +

    Definition at line 2019 of file remmina_file_editor.c.

    @@ -268,7 +268,7 @@ Functions
    -

    Definition at line 2054 of file remmina_file_editor.c.

    +

    Definition at line 2039 of file remmina_file_editor.c.

    @@ -288,7 +288,7 @@ Functions
    -

    Definition at line 1905 of file remmina_file_editor.c.

    +

    Definition at line 1890 of file remmina_file_editor.c.

    @@ -308,7 +308,7 @@ Functions
    -

    Definition at line 2073 of file remmina_file_editor.c.

    +

    Definition at line 2058 of file remmina_file_editor.c.

    @@ -338,7 +338,7 @@ Functions
    -

    Definition at line 2040 of file remmina_file_editor.c.

    +

    Definition at line 2025 of file remmina_file_editor.c.

    diff --git a/public/remmina__file__editor_8h_source.html b/public/remmina__file__editor_8h_source.html index 726670b8e..668a00208 100644 --- a/public/remmina__file__editor_8h_source.html +++ b/public/remmina__file__editor_8h_source.html @@ -89,19 +89,19 @@ $(document).ready(function(){initNavTree('remmina__file__editor_8h_source.html', Go to the documentation of this file.
    1 /*
    2  * Remmina - The GTK+ Remote Desktop Client
    3  * Copyright (C) 2009-2011 Vic Lee
    4  * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
    5  * Copyright (C) 2016-2023 Antenore Gatta, Giovanni Panozzo
    6  *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    15  * GNU General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
    20  * Boston, MA 02110-1301, USA.
    21  *
    22  * In addition, as a special exception, the copyright holders give
    23  * permission to link the code of portions of this program with the
    24  * OpenSSL library under certain conditions as described in each
    25  * individual source file, and distribute linked combinations
    26  * including the two.
    27  * You must obey the GNU General Public License in all respects
    28  * for all of the code used other than OpenSSL. * If you modify
    29  * file(s) with this exception, you may extend this exception to your
    30  * version of the file(s), but you are not obligated to do so. * If you
    31  * do not wish to do so, delete this exception statement from your
    32  * version. * If you delete this exception statement from all source
    33  * files in the program, then also delete it here.
    34  *
    35  */
    36 
    37 #pragma once
    38 
    39 #include <stdarg.h>
    40 #include <glib/gi18n.h>
    41 #include <gtk/gtk.h>
    42 
    43 #include "remmina_file.h"
    44 
    45 G_BEGIN_DECLS
    46 
    47 #define REMMINA_TYPE_FILE_EDITOR (remmina_file_editor_get_type())
    48 #define REMMINA_FILE_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST((obj), REMMINA_TYPE_FILE_EDITOR, RemminaFileEditor))
    49 #define REMMINA_FILE_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST((klass), REMMINA_TYPE_FILE_EDITOR, RemminaFileEditorClass))
    50 #define REMMINA_IS_FILE_EDITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE((obj), REMMINA_TYPE_FILE_EDITOR))
    51 #define REMMINA_IS_FILE_EDITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE((klass), REMMINA_TYPE_FILE_EDITOR))
    52 #define REMMINA_FILE_EDITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), REMMINA_TYPE_FILE_EDITOR, RemminaFileEditorClass))
    53 
    54 typedef struct _RemminaFileEditorPriv RemminaFileEditorPriv;
    55 
    56 typedef struct _RemminaFileEditor {
    57  GtkDialog dialog;
    58 
    61 
    62 typedef struct _RemminaFileEditorClass {
    63  GtkDialogClass parent_class;
    65 
    67 G_GNUC_CONST;
    68 
    69 /* Base constructor */
    70 GtkWidget *remmina_file_editor_new_from_file(RemminaFile *remminafile);
    71 /* Create new file */
    72 GtkWidget *remmina_file_editor_new(void);
    73 GtkWidget *remmina_file_editor_new_full(const gchar *server, const gchar *protocol);
    74 GtkWidget *remmina_file_editor_new_copy(const gchar *filename);
    75 /* Open existing file */
    76 GtkWidget *remmina_file_editor_new_from_filename(const gchar *filename);
    79 
    80 G_END_DECLS
    typedefG_BEGIN_DECLS struct _RemminaFile RemminaFile
    Definition: types.h:44
    struct _RemminaFileEditor RemminaFileEditor
    -
    void remmina_file_editor_check_profile(RemminaFileEditor *gfe)
    +
    void remmina_file_editor_check_profile(RemminaFileEditor *gfe)
    struct _RemminaFileEditorPriv RemminaFileEditorPriv
    -
    void remmina_file_editor_file_save(RemminaFileEditor *gfe)
    -
    GtkWidget * remmina_file_editor_new_copy(const gchar *filename)
    +
    void remmina_file_editor_file_save(RemminaFileEditor *gfe)
    +
    GtkWidget * remmina_file_editor_new_copy(const gchar *filename)
    struct _RemminaFileEditorClass RemminaFileEditorClass
    -
    GtkWidget * remmina_file_editor_new(void)
    +
    GtkWidget * remmina_file_editor_new(void)
    GType remmina_file_editor_get_type(void) G_GNUC_CONST
    -
    GtkWidget * remmina_file_editor_new_from_file(RemminaFile *remminafile)
    -
    GtkWidget * remmina_file_editor_new_from_filename(const gchar *filename)
    -
    GtkWidget * remmina_file_editor_new_full(const gchar *server, const gchar *protocol)
    +
    GtkWidget * remmina_file_editor_new_from_file(RemminaFile *remminafile)
    +
    GtkWidget * remmina_file_editor_new_from_filename(const gchar *filename)
    +
    GtkWidget * remmina_file_editor_new_full(const gchar *server, const gchar *protocol)
    RemminaFileEditorPriv * priv
    diff --git a/public/remmina__main_8c.html b/public/remmina__main_8c.html index 64a3eef00..b8456c019 100644 --- a/public/remmina__main_8c.html +++ b/public/remmina__main_8c.html @@ -202,6 +202,8 @@ Functions   void remmina_main_on_date_column_sort_clicked ()   +void remmina_main_toggle_password_view (GtkWidget *widget, gpointer data) +  static void remmina_main_import_file_list (GSList *files)   static void remmina_main_action_tools_import_on_response (GtkDialog *dialog, gint response_id, gpointer user_data) @@ -342,7 +344,7 @@ Variables
    -

    Definition at line 1315 of file remmina_main.c.

    +

    Definition at line 1333 of file remmina_main.c.

    @@ -386,7 +388,7 @@ Variables
    -

    Definition at line 1204 of file remmina_main.c.

    +

    Definition at line 1222 of file remmina_main.c.

    @@ -430,7 +432,7 @@ Variables
    -

    Definition at line 1534 of file remmina_main.c.

    +

    Definition at line 1552 of file remmina_main.c.

    @@ -638,7 +640,7 @@ Variables
    -

    Definition at line 1450 of file remmina_main.c.

    +

    Definition at line 1468 of file remmina_main.c.

    @@ -674,7 +676,7 @@ Variables
    -

    Definition at line 1473 of file remmina_main.c.

    +

    Definition at line 1491 of file remmina_main.c.

    @@ -716,7 +718,7 @@ Variables
    -

    Definition at line 1432 of file remmina_main.c.

    +

    Definition at line 1450 of file remmina_main.c.

    @@ -818,7 +820,7 @@ Variables
    -

    Definition at line 1718 of file remmina_main.c.

    +

    Definition at line 1736 of file remmina_main.c.

    @@ -866,7 +868,7 @@ Variables
    -

    Definition at line 1161 of file remmina_main.c.

    +

    Definition at line 1179 of file remmina_main.c.

    @@ -895,7 +897,7 @@ Variables
    Todo:
    Set entry_quick_connect_server as default search entry. Weirdly. This does not work yet.
    -

    Definition at line 1553 of file remmina_main.c.

    +

    Definition at line 1571 of file remmina_main.c.

    @@ -1170,7 +1172,7 @@ Variables
    -

    Definition at line 1634 of file remmina_main.c.

    +

    Definition at line 1652 of file remmina_main.c.

    @@ -1226,7 +1228,7 @@ Variables
    -

    Definition at line 1419 of file remmina_main.c.

    +

    Definition at line 1437 of file remmina_main.c.

    @@ -1262,7 +1264,7 @@ Variables
    -

    Definition at line 1309 of file remmina_main.c.

    +

    Definition at line 1327 of file remmina_main.c.

    @@ -1298,7 +1300,7 @@ Variables
    -

    Definition at line 1263 of file remmina_main.c.

    +

    Definition at line 1281 of file remmina_main.c.

    @@ -1406,7 +1408,7 @@ Variables
    -

    Definition at line 1257 of file remmina_main.c.

    +

    Definition at line 1275 of file remmina_main.c.

    @@ -1514,7 +1516,7 @@ Variables
    -

    Definition at line 1396 of file remmina_main.c.

    +

    Definition at line 1414 of file remmina_main.c.

    @@ -1802,7 +1804,7 @@ Variables
    -

    Definition at line 1425 of file remmina_main.c.

    +

    Definition at line 1443 of file remmina_main.c.

    @@ -1838,7 +1840,7 @@ Variables
    -

    Definition at line 1291 of file remmina_main.c.

    +

    Definition at line 1309 of file remmina_main.c.

    @@ -1874,7 +1876,7 @@ Variables
    -

    Definition at line 1303 of file remmina_main.c.

    +

    Definition at line 1321 of file remmina_main.c.

    @@ -1910,7 +1912,7 @@ Variables
    -

    Definition at line 1297 of file remmina_main.c.

    +

    Definition at line 1315 of file remmina_main.c.

    @@ -1946,7 +1948,7 @@ Variables
    -

    Definition at line 1279 of file remmina_main.c.

    +

    Definition at line 1297 of file remmina_main.c.

    @@ -1982,7 +1984,7 @@ Variables
    -

    Definition at line 1285 of file remmina_main.c.

    +

    Definition at line 1303 of file remmina_main.c.

    @@ -2018,7 +2020,7 @@ Variables
    -

    Definition at line 1402 of file remmina_main.c.

    +

    Definition at line 1420 of file remmina_main.c.

    @@ -2054,7 +2056,7 @@ Variables
    -

    Definition at line 1228 of file remmina_main.c.

    +

    Definition at line 1246 of file remmina_main.c.

    @@ -2090,7 +2092,7 @@ Variables
    -

    Definition at line 1216 of file remmina_main.c.

    +

    Definition at line 1234 of file remmina_main.c.

    @@ -2233,7 +2235,7 @@ Variables
    -

    Definition at line 1515 of file remmina_main.c.

    +

    Definition at line 1533 of file remmina_main.c.

    @@ -2263,7 +2265,7 @@ Variables
    -

    Definition at line 1625 of file remmina_main.c.

    +

    Definition at line 1643 of file remmina_main.c.

    @@ -2318,7 +2320,7 @@ Variables
    -

    Definition at line 1546 of file remmina_main.c.

    +

    Definition at line 1564 of file remmina_main.c.

    @@ -2348,7 +2350,7 @@ Variables
    -

    Definition at line 1390 of file remmina_main.c.

    +

    Definition at line 1408 of file remmina_main.c.

    @@ -2378,7 +2380,7 @@ Variables
    -

    Definition at line 1495 of file remmina_main.c.

    +

    Definition at line 1513 of file remmina_main.c.

    @@ -2420,7 +2422,7 @@ Variables
    -

    Definition at line 1488 of file remmina_main.c.

    +

    Definition at line 1506 of file remmina_main.c.

    @@ -2448,7 +2450,7 @@ Variables
    -

    Definition at line 1327 of file remmina_main.c.

    +

    Definition at line 1345 of file remmina_main.c.

    @@ -2478,7 +2480,7 @@ Variables
    -

    Definition at line 1381 of file remmina_main.c.

    +

    Definition at line 1399 of file remmina_main.c.

    @@ -2786,7 +2788,7 @@ Variables
    -

    Definition at line 1737 of file remmina_main.c.

    +

    Definition at line 1755 of file remmina_main.c.

    @@ -2833,7 +2835,37 @@ Variables
    -

    Definition at line 1747 of file remmina_main.c.

    +

    Definition at line 1765 of file remmina_main.c.

    + +
    + + +

    ◆ remmina_main_toggle_password_view()

    + +
    +
    + + + + + + + + + + + + + + + + + + +
    void remmina_main_toggle_password_view (GtkWidget * widget,
    gpointer data 
    )
    +
    + +

    Definition at line 1161 of file remmina_main.c.

    @@ -2903,7 +2935,7 @@ Variables
    -

    Definition at line 1730 of file remmina_main.c.

    +

    Definition at line 1748 of file remmina_main.c.

    @@ -2927,18 +2959,18 @@ Variables
    -Initial value:
    = {
    { "about", remmina_main_on_action_application_about, NULL, NULL, NULL },
    { "default", remmina_main_on_action_application_default, NULL, NULL, NULL },
    { "mpchange", remmina_main_on_action_application_mpchange, NULL, NULL, NULL },
    { "plugins", remmina_main_on_action_application_plugins, NULL, NULL, NULL },
    { "preferences", remmina_main_on_action_application_preferences, "i", NULL, NULL },
    { "dark", remmina_main_on_action_application_dark_theme, NULL, NULL, NULL },
    { "debug", remmina_main_on_action_help_debug, NULL, NULL, NULL },
    { "community", remmina_main_on_action_help_community, NULL, NULL, NULL },
    { "donations", remmina_main_on_action_help_donations, NULL, NULL, NULL },
    { "homepage", remmina_main_on_action_help_homepage, NULL, NULL, NULL },
    { "wiki", remmina_main_on_action_help_wiki, NULL, NULL, NULL },
    { "quit", remmina_main_on_action_application_quit, NULL, NULL, NULL },
    }
    void remmina_main_on_action_help_homepage(GSimpleAction *action, GVariant *param, gpointer data)
    +Initial value:
    = {
    { "about", remmina_main_on_action_application_about, NULL, NULL, NULL },
    { "default", remmina_main_on_action_application_default, NULL, NULL, NULL },
    { "mpchange", remmina_main_on_action_application_mpchange, NULL, NULL, NULL },
    { "plugins", remmina_main_on_action_application_plugins, NULL, NULL, NULL },
    { "preferences", remmina_main_on_action_application_preferences, "i", NULL, NULL },
    { "dark", remmina_main_on_action_application_dark_theme, NULL, NULL, NULL },
    { "debug", remmina_main_on_action_help_debug, NULL, NULL, NULL },
    { "community", remmina_main_on_action_help_community, NULL, NULL, NULL },
    { "donations", remmina_main_on_action_help_donations, NULL, NULL, NULL },
    { "homepage", remmina_main_on_action_help_homepage, NULL, NULL, NULL },
    { "wiki", remmina_main_on_action_help_wiki, NULL, NULL, NULL },
    { "quit", remmina_main_on_action_application_quit, NULL, NULL, NULL },
    }
    void remmina_main_on_action_help_homepage(GSimpleAction *action, GVariant *param, gpointer data)
    void remmina_main_on_action_application_mpchange(GSimpleAction *action, GVariant *param, gpointer data)
    Definition: remmina_main.c:814
    -
    void remmina_main_on_action_help_debug(GSimpleAction *action, GVariant *param, gpointer data)
    -
    void remmina_main_on_action_help_wiki(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_help_debug(GSimpleAction *action, GVariant *param, gpointer data)
    +
    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_on_action_help_donations(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_help_donations(GSimpleAction *action, GVariant *param, gpointer data)
    void remmina_main_on_action_application_preferences(GSimpleAction *action, GVariant *param, gpointer data)
    -
    void remmina_main_on_action_help_community(GSimpleAction *action, GVariant *param, gpointer data)
    -
    void remmina_main_on_action_application_dark_theme(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_help_community(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_application_dark_theme(GSimpleAction *action, GVariant *param, gpointer data)
    void remmina_main_on_action_application_quit(GSimpleAction *action, GVariant *param, gpointer data)
    -
    void remmina_main_on_action_application_about(GSimpleAction *action, GVariant *param, gpointer data)
    -
    void remmina_main_on_action_application_plugins(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_application_about(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_application_plugins(GSimpleAction *action, GVariant *param, gpointer data)

    Definition at line 96 of file remmina_main.c.

    @@ -2964,17 +2996,17 @@ Variables
    Initial value:
    = {
    { "connect", remmina_main_on_action_connection_connect, NULL, NULL, NULL },
    { "copy", remmina_main_on_action_connection_copy, NULL, NULL, NULL },
    { "delete", remmina_main_on_action_connection_delete, NULL, NULL, NULL },
    { "delete_multiple", remmina_main_on_action_connection_delete_multiple, NULL, NULL, NULL },
    { "edit", remmina_main_on_action_connection_edit, NULL, NULL, NULL },
    { "exttools", remmina_main_on_action_connection_external_tools, NULL, NULL, NULL },
    { "new", remmina_main_on_action_connection_new, NULL, NULL, NULL },
    { "export", remmina_main_on_action_tools_export, NULL, NULL, NULL },
    { "import", remmina_main_on_action_tools_import, NULL, NULL, NULL },
    { "expand", remmina_main_on_action_expand, NULL, NULL, NULL },
    { "collapse", remmina_main_on_action_collapse, NULL, NULL, NULL },
    { "search", remmina_main_on_action_search_toggle, NULL, NULL, NULL },
    }
    void remmina_main_on_action_connection_connect(GSimpleAction *action, GVariant *param, gpointer data)
    Definition: remmina_main.c:768
    -
    void remmina_main_on_action_tools_import(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_tools_import(GSimpleAction *action, GVariant *param, gpointer data)
    void remmina_main_on_action_connection_delete_multiple(GSimpleAction *action, GVariant *param, gpointer data)
    void remmina_main_on_action_connection_copy(GSimpleAction *action, GVariant *param, gpointer data)
    Definition: remmina_main.c:910
    -
    void remmina_main_on_action_collapse(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_collapse(GSimpleAction *action, GVariant *param, gpointer data)
    void remmina_main_on_action_connection_new(GSimpleAction *action, GVariant *param, gpointer data)
    Definition: remmina_main.c:851
    void remmina_main_on_action_connection_delete(GSimpleAction *action, GVariant *param, gpointer data)
    Definition: remmina_main.c:977
    void remmina_main_on_action_connection_external_tools(GSimpleAction *action, GVariant *param, gpointer data)
    Definition: remmina_main.c:796
    void remmina_main_on_action_connection_edit(GSimpleAction *action, GVariant *param, gpointer data)
    Definition: remmina_main.c:946
    -
    void remmina_main_on_action_expand(GSimpleAction *action, GVariant *param, gpointer data)
    -
    void remmina_main_on_action_search_toggle(GSimpleAction *action, GVariant *param, gpointer data)
    -
    void remmina_main_on_action_tools_export(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_expand(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_search_toggle(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_tools_export(GSimpleAction *action, GVariant *param, gpointer data)

    Definition at line 111 of file remmina_main.c.

    diff --git a/public/remmina__main_8c.js b/public/remmina__main_8c.js index 51814edf0..f464536f7 100644 --- a/public/remmina__main_8c.js +++ b/public/remmina__main_8c.js @@ -85,6 +85,7 @@ var remmina__main_8c = [ "remmina_main_show_dialog", "remmina__main_8c.html#ab2a1a54320992fb796850ffbd6a63589", null ], [ "remmina_main_show_snap_welcome", "remmina__main_8c.html#ab08aae433b625c3a84330630fe2bd2d5", null ], [ "remmina_main_show_warning_dialog", "remmina__main_8c.html#ad99b9c0bf2fa8c166a8b4a09e06ffdf7", null ], + [ "remmina_main_toggle_password_view", "remmina__main_8c.html#aac3fe305e456dfa7bb55aa2f057e8cb0", null ], [ "remmina_main_tree_row_activated", "remmina__main_8c.html#a4477897686d091d6f57e7f9401674a8c", null ], [ "remmina_main_update_file_datetime", "remmina__main_8c.html#a5ae0372dafe41f96a09097c07d1b270a", null ], [ "app_actions", "remmina__main_8c.html#a923b3e2712d969eb59d9291e99f933e8", null ], diff --git a/public/remmina__main_8c_source.html b/public/remmina__main_8c_source.html index 0de01fd5a..b32c8950d 100644 --- a/public/remmina__main_8c_source.html +++ b/public/remmina__main_8c_source.html @@ -86,7 +86,7 @@ $(document).ready(function(){initNavTree('remmina__main_8c_source.html','');});
    remmina_main.c
    -Go to the documentation of this file.
    1 /*
    2  * Remmina - The GTK+ Remote Desktop Client
    3  * Copyright (C) 2009-2011 Vic Lee
    4  * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
    5  * Copyright (C) 2016-2022 Antenore Gatta, Giovanni Panozzo
    6  * Copyright (C) 2022-2023 Antenore Gatta, Giovanni Panozzo, Hiroyuki Tanaka
    7  *
    8  * This program is free software; you can redistribute it and/or modify
    9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    16  * GNU General Public License for more details.
    17  *
    18  * You should have received a copy of the GNU General Public License
    19  * along with this program; if not, write to the Free Software
    20  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
    21  * Boston, MA 02110-1301, USA.
    22  *
    23  * In addition, as a special exception, the copyright holders give
    24  * permission to link the code of portions of this program with the
    25  * OpenSSL library under certain conditions as described in each
    26  * individual source file, and distribute linked combinations
    27  * including the two.
    28  * You must obey the GNU General Public License in all respects
    29  * for all of the code used other than OpenSSL. * If you modify
    30  * file(s) with this exception, you may extend this exception to your
    31  * version of the file(s), but you are not obligated to do so. * If you
    32  * do not wish to do so, delete this exception statement from your
    33  * version. * If you delete this exception statement from all source
    34  * files in the program, then also delete it here.
    35  *
    36  */
    37 
    38 #include "config.h"
    39 #include <ctype.h>
    40 #include <gio/gio.h>
    41 #ifndef __APPLE__
    42 #include <gio/gdesktopappinfo.h>
    43 #endif
    44 #include <gdk/gdkkeysyms.h>
    45 #include <glib/gi18n.h>
    46 #include <gtk/gtk.h>
    47 
    48 #include "remmina.h"
    49 #include "remmina_string_array.h"
    50 #include "remmina_public.h"
    51 #include "remmina_file.h"
    52 #include "remmina_file_manager.h"
    53 #include "remmina_file_editor.h"
    54 #include "rcw.h"
    55 #include "remmina_about.h"
    56 #include "remmina_pref.h"
    57 #include "remmina_pref_dialog.h"
    58 #include "remmina_widget_pool.h"
    59 #include "remmina_plugin_manager.h"
    60 #include "remmina_log.h"
    61 #include "remmina_icon.h"
    62 #include "remmina_main.h"
    63 #include "remmina_exec.h"
    64 #include "remmina_mpchange.h"
    65 #include "remmina_external_tools.h"
    66 #include "remmina_unlock.h"
    68 
    70 
    71 #define RM_GET_OBJECT(object_name) gtk_builder_get_object(remminamain->builder, object_name)
    72 
    73 enum {
    84 };
    85 
    86 static
    87 const gchar *supported_mime_types[] = {
    88  "x-scheme-handler/rdp",
    89  "x-scheme-handler/spice",
    90  "x-scheme-handler/vnc",
    91  "x-scheme-handler/remmina",
    92  "application/x-remmina",
    93  NULL
    94 };
    95 
    96 static GActionEntry app_actions[] = {
    97  { "about", remmina_main_on_action_application_about, NULL, NULL, NULL },
    98  { "default", remmina_main_on_action_application_default, NULL, NULL, NULL },
    99  { "mpchange", remmina_main_on_action_application_mpchange, NULL, NULL, NULL },
    100  { "plugins", remmina_main_on_action_application_plugins, NULL, NULL, NULL },
    101  { "preferences", remmina_main_on_action_application_preferences, "i", NULL, NULL },
    102  { "dark", remmina_main_on_action_application_dark_theme, NULL, NULL, NULL },
    103  { "debug", remmina_main_on_action_help_debug, NULL, NULL, NULL },
    104  { "community", remmina_main_on_action_help_community, NULL, NULL, NULL },
    105  { "donations", remmina_main_on_action_help_donations, NULL, NULL, NULL },
    106  { "homepage", remmina_main_on_action_help_homepage, NULL, NULL, NULL },
    107  { "wiki", remmina_main_on_action_help_wiki, NULL, NULL, NULL },
    108  { "quit", remmina_main_on_action_application_quit, NULL, NULL, NULL },
    109 };
    110 
    111 static GActionEntry main_actions[] = {
    112  { "connect", remmina_main_on_action_connection_connect, NULL, NULL, NULL },
    113  { "copy", remmina_main_on_action_connection_copy, NULL, NULL, NULL },
    114  { "delete", remmina_main_on_action_connection_delete, NULL, NULL, NULL },
    115  { "delete_multiple", remmina_main_on_action_connection_delete_multiple, NULL, NULL, NULL },
    116  { "edit", remmina_main_on_action_connection_edit, NULL, NULL, NULL },
    117  { "exttools", remmina_main_on_action_connection_external_tools, NULL, NULL, NULL },
    118  { "new", remmina_main_on_action_connection_new, NULL, NULL, NULL },
    119  { "export", remmina_main_on_action_tools_export, NULL, NULL, NULL },
    120  { "import", remmina_main_on_action_tools_import, NULL, NULL, NULL },
    121  { "expand", remmina_main_on_action_expand, NULL, NULL, NULL },
    122  { "collapse", remmina_main_on_action_collapse, NULL, NULL, NULL },
    123  { "search", remmina_main_on_action_search_toggle, NULL, NULL, NULL },
    124 };
    125 
    126 static GtkTargetEntry remmina_drop_types[] =
    127 {
    128  { "text/uri-list", 0, 1 }
    129 };
    130 
    132 {
    133  "RDP", "VNC", "SSH", "NX", "SPICE", "X2GO"
    134 };
    135 
    139 static void remmina_main_save_size(void)
    140 {
    141  TRACE_CALL(__func__);
    142  if ((gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(remminamain->window))) & GDK_WINDOW_STATE_MAXIMIZED) == 0) {
    143  gtk_window_get_size(remminamain->window, &remmina_pref.main_width, &remmina_pref.main_height);
    144  remmina_pref.main_maximize = FALSE;
    145  } else {
    147  }
    148 }
    149 
    150 static void remmina_main_save_expanded_group_func(GtkTreeView *tree_view, GtkTreePath *path, gpointer user_data)
    151 {
    152  TRACE_CALL(__func__);
    153  GtkTreeIter iter;
    154  gchar *group;
    155 
    156  gtk_tree_model_get_iter(remminamain->priv->file_model_sort, &iter, path);
    157  gtk_tree_model_get(remminamain->priv->file_model_sort, &iter, GROUP_COLUMN, &group, -1);
    158  if (group) {
    159  remmina_string_array_add(remminamain->priv->expanded_group, group);
    160  g_free(group);
    161  }
    162 }
    163 
    165 {
    166  TRACE_CALL(__func__);
    167  if (GTK_IS_TREE_STORE(remminamain->priv->file_model)) {
    168  if (remminamain->priv->expanded_group)
    170  remminamain->priv->expanded_group = remmina_string_array_new();
    171  gtk_tree_view_map_expanded_rows(remminamain->tree_files_list,
    172  (GtkTreeViewMappingFunc)remmina_main_save_expanded_group_func, NULL);
    173  }
    174 }
    175 
    181 {
    182  TRACE_CALL(__func__);
    183  if (!remminamain || !remminamain->window)
    184  return;
    185 
    191 }
    192 
    194 {
    195  TRACE_CALL(__func__);
    196 
    197  if (remminamain) {
    198  if (remminamain->window)
    199  gtk_widget_destroy(GTK_WIDGET(remminamain->window));
    200 
    201  g_object_unref(remminamain->builder);
    203  remminamain->priv->expanded_group = NULL;
    204  if (remminamain->priv->file_model)
    205  g_object_unref(G_OBJECT(remminamain->priv->file_model));
    206  g_object_unref(G_OBJECT(remminamain->priv->file_model_filter));
    207  g_free(remminamain->priv->selected_filename);
    208  g_free(remminamain->priv->selected_name);
    209  g_free(remminamain->priv);
    210  g_free(remminamain);
    211  remminamain = NULL;
    212  }
    213 }
    214 
    218 static gboolean remmina_main_dexit(gpointer data)
    219 {
    220  TRACE_CALL(__func__);
    222  return FALSE;
    223 }
    224 
    225 gboolean remmina_main_on_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
    226 {
    227  TRACE_CALL(__func__);
    229 
    230  g_idle_add(remmina_main_dexit, NULL);
    231 
    232  return FALSE;
    233 }
    234 
    235 gboolean remmina_main_idle_destroy(gpointer data)
    236 {
    237  TRACE_CALL(__func__);
    238 
    239  if (remminamain)
    241 
    242  return G_SOURCE_REMOVE;
    243 }
    244 
    249 {
    250  TRACE_CALL(__func__);
    251 
    252  if (remminamain) {
    253  /* Invalidate remminamain->window to avoid multiple destructions */
    254  remminamain->window = NULL;
    255  /* Destroy remminamain struct, later. We can't destroy
    256  * important objects like the builder now */
    257  g_idle_add(remmina_main_idle_destroy, NULL);
    258  }
    259 }
    260 
    262 {
    263  TRACE_CALL(__func__);
    264  g_free(remminamain->priv->selected_filename);
    265  g_free(remminamain->priv->selected_name);
    266  remminamain->priv->selected_filename = NULL;
    267  remminamain->priv->selected_name = NULL;
    268 }
    269 
    270 #ifdef SNAP_BUILD
    271 
    273 {
    274  GtkBuilder *dlgbuilder = NULL;
    275  GtkWidget *dlg;
    276  GtkWindow *parent;
    277  int result;
    278  static gboolean shown_once = FALSE;
    279  gboolean need_snap_interface_connections = FALSE;
    280  GtkWidget *dsa;
    282 
    283  if (shown_once)
    284  return;
    285  else
    286  shown_once = TRUE;
    287 
    288  g_print("Remmina is compiled as a SNAP package.\n");
    289  remmina_secret_plugin = remmina_plugin_manager_get_secret_plugin();
    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;
    293  } else {
    294  if (!remmina_secret_plugin->is_service_available(remmina_secret_plugin)) {
    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;
    297  }
    298  }
    299 
    300  if (need_snap_interface_connections && !remmina_pref.prevent_snap_welcome_message) {
    301  dlgbuilder = remmina_public_gtk_builder_new_from_resource("/org/remmina/Remmina/src/../data/ui/remmina_snap_info_dialog.glade");
    302  dsa = GTK_WIDGET(gtk_builder_get_object(dlgbuilder, "dontshowagain"));
    303  if (dlgbuilder) {
    304  parent = remmina_main_get_window();
    305  dlg = GTK_WIDGET(gtk_builder_get_object(dlgbuilder, "SnapInfoDlg"));
    306  if (parent)
    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));
    310  if (result == 1) {
    311  remmina_pref.prevent_snap_welcome_message = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dsa));
    313  }
    314  gtk_widget_destroy(dlg);
    315  g_object_unref(dlgbuilder);
    316  }
    317  }
    318 }
    319 #endif
    320 
    321 
    322 static gboolean remmina_main_selection_func(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path,
    323  gboolean path_currently_selected, gpointer user_data)
    324 {
    325  TRACE_CALL(__func__);
    326  guint context_id;
    327  GtkTreeIter iter;
    328  gchar buf[1000];
    329 
    330  if (path_currently_selected)
    331  return TRUE;
    332 
    333  if (!gtk_tree_model_get_iter(model, &iter, path))
    334  return TRUE;
    335 
    337 
    338  gtk_tree_model_get(model, &iter,
    339  NAME_COLUMN, &remminamain->priv->selected_name,
    340  FILENAME_COLUMN, &remminamain->priv->selected_filename,
    341  -1);
    342 
    343  context_id = gtk_statusbar_get_context_id(remminamain->statusbar_main, "status");
    344  gtk_statusbar_pop(remminamain->statusbar_main, context_id);
    345  if (remminamain->priv->selected_filename) {
    346  g_snprintf(buf, sizeof(buf), "%s (%s)", remminamain->priv->selected_name, remminamain->priv->selected_filename);
    347  gtk_statusbar_push(remminamain->statusbar_main, context_id, buf);
    348  } else {
    349  gtk_statusbar_push(remminamain->statusbar_main, context_id, remminamain->priv->selected_name);
    350  }
    351 
    352  return TRUE;
    353 }
    354 
    355 static void remmina_main_load_file_list_callback(RemminaFile *remminafile, gpointer user_data)
    356 {
    357  TRACE_CALL(__func__);
    358  GtkTreeIter iter;
    359  GtkListStore *store;
    360 
    361  store = GTK_LIST_STORE(user_data);
    362  gchar *datetime;
    363 
    364  datetime = remmina_file_get_datetime(remminafile);
    365  gtk_list_store_append(store, &iter);
    366  gtk_list_store_set(store, &iter,
    368  NAME_COLUMN, remmina_file_get_string(remminafile, "name"),
    369  NOTES_COLUMN, g_uri_unescape_string(remmina_file_get_string(remminafile, "notes_text"), NULL),
    370  GROUP_COLUMN, remmina_file_get_string(remminafile, "group"),
    371  SERVER_COLUMN, remmina_file_get_string(remminafile, "server"),
    372  PLUGIN_COLUMN, remmina_file_get_string(remminafile, "protocol"),
    373  DATE_COLUMN, datetime,
    375  LABELS_COLUMN, remmina_file_get_string(remminafile, "labels"),
    376  -1);
    377  g_free(datetime);
    378 }
    379 
    380 static gboolean remmina_main_load_file_tree_traverse(GNode *node, GtkTreeStore *store, GtkTreeIter *parent)
    381 {
    382  TRACE_CALL(__func__);
    383  GtkTreeIter *iter;
    384  RemminaGroupData *data;
    385  GNode *child;
    386 
    387  iter = NULL;
    388  if (node->data) {
    389  data = (RemminaGroupData *)node->data;
    390  iter = g_new0(GtkTreeIter, 1);
    391  gtk_tree_store_append(store, iter, parent);
    392  gtk_tree_store_set(store, iter,
    393  PROTOCOL_COLUMN, "folder-symbolic",
    394  NAME_COLUMN, data->name,
    395  GROUP_COLUMN, data->group,
    396  DATE_COLUMN, data->datetime,
    397  FILENAME_COLUMN, NULL,
    398  LABELS_COLUMN, data->labels,
    399  -1);
    400  }
    401  for (child = g_node_first_child(node); child; child = g_node_next_sibling(child))
    402  remmina_main_load_file_tree_traverse(child, store, iter);
    403  g_free(iter);
    404  return FALSE;
    405 }
    406 
    407 static void remmina_main_load_file_tree_group(GtkTreeStore *store)
    408 {
    409  TRACE_CALL(__func__);
    410  GNode *root;
    411 
    413  remmina_main_load_file_tree_traverse(root, store, NULL);
    415 }
    416 
    417 static void remmina_main_expand_group_traverse(GtkTreeIter *iter)
    418 {
    419  TRACE_CALL(__func__);
    420  GtkTreeModel *tree;
    421  gboolean ret;
    422  gchar *group, *filename;
    423  GtkTreeIter child;
    424  GtkTreePath *path;
    425 
    426  tree = remminamain->priv->file_model_sort;
    427  ret = TRUE;
    428  while (ret) {
    429  gtk_tree_model_get(tree, iter, GROUP_COLUMN, &group, FILENAME_COLUMN, &filename, -1);
    430  if (filename == NULL) {
    431  if (remmina_string_array_find(remminamain->priv->expanded_group, group) >= 0) {
    432  path = gtk_tree_model_get_path(tree, iter);
    433  gtk_tree_view_expand_row(remminamain->tree_files_list, path, FALSE);
    434  gtk_tree_path_free(path);
    435  }
    436  if (gtk_tree_model_iter_children(tree, &child, iter))
    438  }
    439  g_free(group);
    440  g_free(filename);
    441 
    442  ret = gtk_tree_model_iter_next(tree, iter);
    443  }
    444 }
    445 
    446 static void remmina_main_expand_group(void)
    447 {
    448  TRACE_CALL(__func__);
    449  GtkTreeIter iter;
    450 
    451  if (gtk_tree_model_get_iter_first(remminamain->priv->file_model_sort, &iter))
    453 }
    454 
    455 static gboolean remmina_main_load_file_tree_find(GtkTreeModel *tree, GtkTreeIter *iter, const gchar *match_group)
    456 {
    457  TRACE_CALL(__func__);
    458  gboolean ret, match;
    459  gchar *group, *filename;
    460  GtkTreeIter child;
    461 
    462  match = FALSE;
    463  ret = TRUE;
    464  while (ret) {
    465  gtk_tree_model_get(tree, iter, GROUP_COLUMN, &group, FILENAME_COLUMN, &filename, -1);
    466  match = (filename == NULL && g_strcmp0(group, match_group) == 0);
    467  g_free(group);
    468  g_free(filename);
    469  if (match)
    470  break;
    471  if (gtk_tree_model_iter_children(tree, &child, iter)) {
    472  match = remmina_main_load_file_tree_find(tree, &child, match_group);
    473  if (match) {
    474  memcpy(iter, &child, sizeof(GtkTreeIter));
    475  break;
    476  }
    477  }
    478  ret = gtk_tree_model_iter_next(tree, iter);
    479  }
    480  return match;
    481 }
    482 
    483 static void remmina_main_load_file_tree_callback(RemminaFile *remminafile, gpointer user_data)
    484 {
    485  TRACE_CALL(__func__);
    486  GtkTreeIter iter, child;
    487  GtkTreeStore *store;
    488  gboolean found;
    489  gchar *datetime = NULL;
    490 
    491  store = GTK_TREE_STORE(user_data);
    492 
    493  found = FALSE;
    494  if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter))
    495  found = remmina_main_load_file_tree_find(GTK_TREE_MODEL(store), &iter,
    496  remmina_file_get_string(remminafile, "group"));
    497 
    498  datetime = remmina_file_get_datetime(remminafile);
    499  //REMMINA_DEBUG("The date is %s", datetime);
    500  gtk_tree_store_append(store, &child, (found ? &iter : NULL));
    501  gtk_tree_store_set(store, &child,
    503  NAME_COLUMN, remmina_file_get_string(remminafile, "name"),
    504  NOTES_COLUMN, g_uri_unescape_string(remmina_file_get_string(remminafile, "notes_text"), NULL),
    505  GROUP_COLUMN, remmina_file_get_string(remminafile, "group"),
    506  SERVER_COLUMN, remmina_file_get_string(remminafile, "server"),
    507  PLUGIN_COLUMN, remmina_file_get_string(remminafile, "protocol"),
    508  DATE_COLUMN, datetime,
    510  LABELS_COLUMN, remmina_file_get_string(remminafile, "labels"),
    511  -1);
    512  g_free(datetime);
    513 }
    514 
    515 static void remmina_main_file_model_on_sort(GtkTreeSortable *sortable, gpointer user_data)
    516 {
    517  TRACE_CALL(__func__);
    518  gint columnid;
    519  GtkSortType order;
    520 
    521  gtk_tree_sortable_get_sort_column_id(sortable, &columnid, &order);
    525 }
    526 
    527 static gboolean remmina_main_filter_visible_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
    528 {
    529  TRACE_CALL(__func__);
    530  gchar *text;
    531  gchar *protocol, *name, *labels, *group, *server, *plugin, *date, *s;
    532  gboolean result = TRUE;
    533 
    534  text = g_ascii_strdown(gtk_entry_get_text(remminamain->entry_quick_connect_server), -1);
    535  if (text && text[0]) {
    536  gtk_tree_model_get(model, iter,
    537  PROTOCOL_COLUMN, &protocol,
    538  NAME_COLUMN, &name,
    539  GROUP_COLUMN, &group,
    540  SERVER_COLUMN, &server,
    541  PLUGIN_COLUMN, &plugin,
    542  DATE_COLUMN, &date,
    543  LABELS_COLUMN, &labels,
    544  -1);
    545  if (g_strcmp0(protocol, "folder-symbolic") != 0) {
    546  s = g_ascii_strdown(name ? name : "", -1);
    547  g_free(name);
    548  name = s;
    549  s = g_ascii_strdown(group ? group : "", -1);
    550  g_free(group);
    551  group = s;
    552  s = g_ascii_strdown(server ? server : "", -1);
    553  g_free(server);
    554  server = s;
    555  s = g_ascii_strdown(plugin ? plugin : "", -1);
    556  g_free(plugin);
    557  plugin = s;
    558  s = g_ascii_strdown(date ? date : "", -1);
    559  g_free(date);
    560  date = s;
    561  result = (strstr(name, text) || strstr(group, text) || strstr(server, text) || strstr(plugin, text) || strstr(date, text));
    562 
    563  // Filter by labels
    564 
    565  s = g_ascii_strdown(labels ? labels : "", -1);
    566  g_free(labels);
    567  labels = s;
    568 
    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);
    573 
    574  for (int t = 0; (NULL != text_array[t]); t++) {
    575  if (0 == strlen(text_array[t])) {
    576  continue;
    577  }
    578 
    579  gboolean text_result = FALSE;
    580 
    581  for (int l = 0; (NULL != labels_array[l]); l++) {
    582  if (0 == strlen(labels_array[l])) {
    583  continue;
    584  }
    585 
    586  text_result = (text_result || strstr(labels_array[l], text_array[t]));
    587 
    588  if (text_result) {
    589  break;
    590  }
    591  }
    592 
    593  labels_result = (labels_result && text_result);
    594 
    595  if (!labels_result) {
    596  break;
    597  }
    598  }
    599 
    600  result = (result || labels_result);
    601 
    602  g_strfreev(labels_array);
    603  g_strfreev(text_array);
    604  }
    605  }
    606  g_free(protocol);
    607  g_free(name);
    608  g_free(labels);
    609  g_free(group);
    610  g_free(server);
    611  g_free(plugin);
    612  g_free(date);
    613  }
    614  g_free(text);
    615  return result;
    616 }
    617 
    618 static void remmina_main_select_file(const gchar *filename)
    619 {
    620  TRACE_CALL(__func__);
    621  GtkTreeIter iter;
    622  GtkTreePath *path;
    623  gchar *item_filename;
    624  gboolean cmp;
    625 
    626  if (!gtk_tree_model_get_iter_first(remminamain->priv->file_model_sort, &iter))
    627  return;
    628 
    629  while (TRUE) {
    630  gtk_tree_model_get(remminamain->priv->file_model_sort, &iter, FILENAME_COLUMN, &item_filename, -1);
    631  cmp = g_strcmp0(item_filename, filename);
    632  g_free(item_filename);
    633  if (cmp == 0) {
    634  gtk_tree_selection_select_iter(gtk_tree_view_get_selection(remminamain->tree_files_list),
    635  &iter);
    636  path = gtk_tree_model_get_path(remminamain->priv->file_model_sort, &iter);
    637  gtk_tree_view_scroll_to_cell(remminamain->tree_files_list, path, NULL, TRUE, 0.5, 0.0);
    638  gtk_tree_path_free(path);
    639  return;
    640  }
    641  if (!gtk_tree_model_iter_next(remminamain->priv->file_model_sort, &iter))
    642  return;
    643  }
    644 }
    645 
    647 {
    648  TRACE_CALL(__func__);
    649  gint items_count;
    650  gchar buf[200];
    651  guint context_id;
    652  gint view_file_mode;
    653  gboolean always_show_notes;
    654  char *save_selected_filename;
    655  GtkTreeModel *newmodel;
    656  const gchar *neticon;
    657  const gchar *connection_tooltip;
    658 
    659  save_selected_filename = g_strdup(remminamain->priv->selected_filename);
    661 
    662  view_file_mode = remmina_pref.view_file_mode;
    663  if (remminamain->priv->override_view_file_mode_to_list)
    664  view_file_mode = REMMINA_VIEW_FILE_LIST;
    665 
    666  switch (remmina_pref.view_file_mode) {
    668  gtk_toggle_button_set_active(remminamain->view_toggle_button, FALSE);
    669  break;
    671  default:
    672  gtk_toggle_button_set_active(remminamain->view_toggle_button, TRUE);
    673  break;
    674  }
    675 
    676  switch (view_file_mode) {
    678  /* Create new GtkTreeStore model */
    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));
    680  /* Hide the Group column in the tree view mode */
    681  gtk_tree_view_column_set_visible(remminamain->column_files_list_group, FALSE);
    682  /* Load groups first */
    683  remmina_main_load_file_tree_group(GTK_TREE_STORE(newmodel));
    684  /* Load files list */
    685  items_count = remmina_file_manager_iterate((GFunc)remmina_main_load_file_tree_callback, (gpointer)newmodel);
    686  break;
    687 
    689  default:
    690  /* Create new GtkListStore model */
    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));
    692  /* Show the Group column in the list view mode */
    693  gtk_tree_view_column_set_visible(remminamain->column_files_list_group, TRUE);
    694  /* Load files list */
    695  items_count = remmina_file_manager_iterate((GFunc)remmina_main_load_file_list_callback, (gpointer)newmodel);
    696  break;
    697  }
    698 
    699  /* Set note column visibility*/
    700  always_show_notes = remmina_pref.always_show_notes;
    701  if (!always_show_notes){
    702  gtk_tree_view_column_set_visible(remminamain->column_files_list_notes, FALSE);
    703  }
    704 
    705  /* Unset old model */
    706  gtk_tree_view_set_model(remminamain->tree_files_list, NULL);
    707 
    708  /* Destroy the old model and save the new one */
    709  remminamain->priv->file_model = newmodel;
    710 
    711  /* Create a sorted filtered model based on newmodel and apply it to the TreeView */
    712  remminamain->priv->file_model_filter = gtk_tree_model_filter_new(remminamain->priv->file_model, NULL);
    713  gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(remminamain->priv->file_model_filter),
    714  (GtkTreeModelFilterVisibleFunc)remmina_main_filter_visible_func, NULL, NULL);
    715  remminamain->priv->file_model_sort = gtk_tree_model_sort_new_with_model(remminamain->priv->file_model_filter);
    716  gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(remminamain->priv->file_model_sort),
    719  gtk_tree_view_set_model(remminamain->tree_files_list, remminamain->priv->file_model_sort);
    720  g_signal_connect(G_OBJECT(remminamain->priv->file_model_sort), "sort-column-changed",
    721  G_CALLBACK(remmina_main_file_model_on_sort), NULL);
    723  /* Select the file previously selected */
    724  if (save_selected_filename) {
    725  remmina_main_select_file(save_selected_filename);
    726  g_free(save_selected_filename);
    727  }
    728  gtk_tree_view_column_set_widget(remminamain->column_files_list_date, NULL);
    729 
    730  GtkWidget *label = gtk_tree_view_column_get_button(remminamain->column_files_list_date);
    731 
    732  gtk_widget_set_tooltip_text(GTK_WIDGET(label),
    733  _("The latest successful connection attempt, or a pre-computed date"));
    734  /* Show in the status bar the total number of connections found */
    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");
    737  gtk_statusbar_pop(remminamain->statusbar_main, context_id);
    738  gtk_statusbar_push(remminamain->statusbar_main, context_id, buf);
    739 
    741  if (remminamain->monitor->connected){
    742  neticon = g_strdup("network-transmit-receive-symbolic");
    743  connection_tooltip = g_strdup(_("Network status: fully online"));
    744  } else {
    745  neticon = g_strdup("network-offline-symbolic");
    746  connection_tooltip = g_strdup(_("Network status: offline"));
    747  }
    748 
    749  if (GTK_IS_WIDGET(remminamain->network_icon))
    750  gtk_widget_destroy(remminamain->network_icon);
    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);
    754 
    755  g_object_unref (icon);
    756 
    757  gtk_box_pack_start (GTK_BOX(remminamain->statusbar_main), remminamain->network_icon, FALSE, FALSE, 0);
    758  gtk_widget_show (remminamain->network_icon);
    759 
    760 }
    761 
    762 void remmina_main_load_files_cb(GtkEntry *entry, char *string, gpointer user_data)
    763 {
    764  TRACE_CALL(__func__);
    766 }
    767 
    768 void remmina_main_on_action_connection_connect(GSimpleAction *action, GVariant *param, gpointer data)
    769 {
    770  TRACE_CALL(__func__);
    771 
    772  RemminaFile *remminafile;
    773 
    774  if (!remminamain->priv->selected_filename)
    775  return;
    776 
    777  remminafile = remmina_file_load(remminamain->priv->selected_filename);
    778 
    779  if (remminafile == NULL)
    780  return;
    781 
    782  if (remmina_pref_get_boolean("use_primary_password")
    783  && remmina_pref_get_boolean("lock_connect")
    784  && remmina_unlock_new(remminamain->window) == 0)
    785  return;
    786  if (remmina_file_get_int (remminafile, "profile-lock", FALSE) == 1
    787  && remmina_unlock_new(remminamain->window) == 0)
    788  return;
    789 
    790  remmina_file_touch(remminafile);
    792 
    793  remmina_file_free(remminafile);
    794 }
    795 
    796 void remmina_main_on_action_connection_external_tools(GSimpleAction *action, GVariant *param, gpointer data)
    797 {
    798  TRACE_CALL(__func__);
    799  if (!remminamain->priv->selected_filename)
    800  return;
    801 
    802  remmina_external_tools_from_filename(remminamain, remminamain->priv->selected_filename);
    803 }
    804 
    805 static void remmina_main_file_editor_destroy(GtkWidget *widget, gpointer user_data)
    806 {
    807  TRACE_CALL(__func__);
    808 
    809  if (!remminamain)
    810  return;
    812 }
    813 
    814 void remmina_main_on_action_application_mpchange(GSimpleAction *action, GVariant *param, gpointer data)
    815 {
    816  TRACE_CALL(__func__);
    817  RemminaFile *remminafile;
    818 
    819  const gchar *username;
    820  const gchar *domain;
    821  const gchar *group;
    822  const gchar *gatewayusername;
    823  const gchar *gatewaydomain;
    824 
    825  username = domain = group = gatewayusername = gatewaydomain = "";
    826 
    827  remminafile = NULL;
    828 
    829  if (remmina_pref_get_boolean("use_primary_password")
    830  && remmina_pref_get_boolean("lock_edit")
    831  && remmina_unlock_new(remminamain->window) == 0)
    832  return;
    833 
    834  if (remminamain->priv->selected_filename) {
    835  remminafile = remmina_file_load(remminamain->priv->selected_filename);
    836  if (remminafile != NULL) {
    837  username = remmina_file_get_string(remminafile, "username");
    838  domain = remmina_file_get_string(remminafile, "domain");
    839  group = remmina_file_get_string(remminafile, "group");
    840  gatewayusername = remmina_file_get_string(remminafile, "gateway_username");
    841  gatewaydomain = remmina_file_get_string(remminafile, "gateway_domain");
    842  }
    843  }
    844 
    845  remmina_mpchange_schedule(TRUE, group, domain, username, "", gatewayusername, gatewaydomain, "");
    846 
    847  if (remminafile != NULL)
    848  remmina_file_free(remminafile);
    849 }
    850 
    851 void remmina_main_on_action_connection_new(GSimpleAction *action, GVariant *param, gpointer data)
    852 {
    853  TRACE_CALL(__func__);
    854  if (kioskmode && kioskmode == TRUE)
    855  return;
    856  GtkWidget *widget;
    857 
    858  if (remmina_pref_get_boolean("use_primary_password")
    859  && remmina_pref_get_boolean("lock_edit")
    860  && remmina_unlock_new(remminamain->window) == 0)
    861  return;
    862 
    863  widget = remmina_file_editor_new();
    864  g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(remmina_main_file_editor_destroy), remminamain);
    865  gtk_window_set_transient_for(GTK_WINDOW(widget), remminamain->window);
    866  gtk_widget_show(widget);
    868 }
    869 
    870 static gboolean remmina_main_search_key_event(GtkWidget *search_entry, GdkEventKey *event, gpointer user_data)
    871 {
    872  TRACE_CALL(__func__);
    873  if (event->keyval == GDK_KEY_Escape) {
    874  gtk_entry_set_text(remminamain->entry_quick_connect_server, "");
    875  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(RM_GET_OBJECT("search_toggle")), FALSE);
    876  return TRUE;
    877  }
    878  return FALSE;
    879 }
    880 
    881 static gboolean remmina_main_tree_row_activated(GtkTreeView *tree, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data)
    882 {
    883  TRACE_CALL(__func__);
    884  if (gtk_tree_view_row_expanded(tree, path))
    885  gtk_tree_view_collapse_row(tree, path);
    886  else
    887  gtk_tree_view_expand_row(tree, path, FALSE);
    888  return TRUE;
    889 }
    890 
    892 {
    893  if (gtk_toggle_button_get_active(remminamain->view_toggle_button)) {
    896  gtk_entry_set_text(remminamain->entry_quick_connect_server, "");
    899  }
    900  } else {
    903  gtk_entry_set_text(remminamain->entry_quick_connect_server, "");
    906  }
    907  }
    908 }
    909 
    910 void remmina_main_on_action_connection_copy(GSimpleAction *action, GVariant *param, gpointer data)
    911 {
    912  TRACE_CALL(__func__);
    913  GtkWidget *widget;
    914 
    915  if (remmina_pref_get_boolean("use_primary_password")
    916  && remmina_unlock_new(remminamain->window) == 0)
    917  return;
    918 
    919  if (!remminamain->priv->selected_filename)
    920  return;
    921 
    922  RemminaFile *remminafile = remmina_file_load(remminamain->priv->selected_filename);
    923 
    924  if (((remmina_pref_get_boolean("lock_edit")
    925  && remmina_pref_get_boolean("use_primary_password"))
    926  || remmina_file_get_int (remminafile, "profile-lock", FALSE))
    927  && remmina_unlock_new(remminamain->window) == 0)
    928  return;
    929 
    930  if (remminafile) {
    931  remmina_file_free(remminafile);
    932  remminafile = NULL;
    933  }
    934 
    935  widget = remmina_file_editor_new_copy(remminamain->priv->selected_filename);
    936  if (widget) {
    937  g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(remmina_main_file_editor_destroy), remminamain);
    938  gtk_window_set_transient_for(GTK_WINDOW(widget), remminamain->window);
    939  gtk_widget_show(widget);
    940  }
    941  /* Select the file previously selected */
    942  if (remminamain->priv->selected_filename)
    944 }
    945 
    946 void remmina_main_on_action_connection_edit(GSimpleAction *action, GVariant *param, gpointer data)
    947 {
    948  TRACE_CALL(__func__);
    949  GtkWidget *widget;
    950 
    951  if (!remminamain->priv->selected_filename)
    952  return;
    953 
    954  RemminaFile *remminafile = remmina_file_load(remminamain->priv->selected_filename);
    955 
    956  if (remmina_pref_get_boolean("use_primary_password")
    957  && (remmina_pref_get_boolean("lock_edit")
    958  || remmina_file_get_int (remminafile, "profile-lock", FALSE))
    959  && remmina_unlock_new(remminamain->window) == 0)
    960  return;
    961 
    962  if (remminafile) {
    963  remmina_file_free(remminafile);
    964  remminafile = NULL;
    965  }
    966 
    968  if (widget) {
    969  gtk_window_set_transient_for(GTK_WINDOW(widget), remminamain->window);
    970  gtk_widget_show(widget);
    971  }
    972 /* Select the file previously selected */
    973  if (remminamain->priv->selected_filename)
    975 }
    976 
    977 void remmina_main_on_action_connection_delete(GSimpleAction *action, GVariant *param, gpointer data)
    978 {
    979  TRACE_CALL(__func__);
    980  GtkWidget *dialog;
    981 
    982  if (!remminamain->priv->selected_filename)
    983  return;
    984 
    985  RemminaFile *remminafile = remmina_file_load(remminamain->priv->selected_filename);
    986 
    987  if (((remmina_pref_get_boolean("lock_edit")
    988  && remmina_pref_get_boolean("use_primary_password"))
    989  || remmina_file_get_int (remminafile, "profile-lock", FALSE))
    990  && remmina_unlock_new(remminamain->window) == 0)
    991  return;
    992 
    993  if (remminafile) {
    994  remmina_file_free(remminafile);
    995  remminafile = NULL;
    996  }
    997 
    998  dialog = gtk_message_dialog_new(remminamain->window, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
    999  _("Are you sure you want to delete “%s”?"), remminamain->priv->selected_name);
    1000  if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_YES) {
    1001  gchar *delfilename = g_strdup(remminamain->priv->selected_filename);
    1002  remmina_file_delete(delfilename);
    1003  g_free(delfilename), delfilename = NULL;
    1006  }
    1007  gtk_widget_destroy(dialog);
    1009 }
    1010 
    1011 void remmina_main_on_action_connection_delete_multiple(GSimpleAction *action, GVariant *param, gpointer data)
    1012 {
    1013  TRACE_CALL(__func__);
    1014  GtkWidget *dialog;
    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;
    1019 
    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?"));
    1022 
    1023  // Delete files if Yes is clicked
    1024  if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_YES) {
    1025  while (list) {
    1026  GtkTreePath *path = list->data;
    1027  GtkTreeIter iter;
    1028 
    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);
    1037  return;
    1038  }
    1039 
    1040  gtk_tree_model_get(model, &iter,
    1041  FILENAME_COLUMN, &file_to_delete, -1);
    1042 
    1043  RemminaFile *remminafile = remmina_file_load(file_to_delete);
    1044 
    1045  if (((remmina_pref_get_boolean("lock_edit")
    1046  && remmina_pref_get_boolean("use_primary_password"))
    1047  || remmina_file_get_int (remminafile, "profile-lock", FALSE))
    1048  && remmina_unlock_new(remminamain->window) == 0)
    1049  return;
    1050 
    1051  if (remminafile) {
    1052  remmina_file_free(remminafile);
    1053  remminafile = NULL;
    1054  }
    1055 
    1056  gchar *delfilename = g_strdup(file_to_delete);
    1057  remmina_file_delete(delfilename);
    1058  g_free(delfilename), delfilename = NULL;
    1061  list = g_list_next(list);
    1062  }
    1063  }
    1064 
    1065  gtk_widget_destroy(dialog);
    1067 }
    1068 
    1069 void remmina_main_on_accel_application_preferences(GSimpleAction *action, GVariant *param, gpointer data)
    1070 {
    1071  TRACE_CALL(__func__);
    1072  GVariant *v = g_variant_new("i", 0);
    1073 
    1075 }
    1076 
    1078 {
    1079  GtkSettings *settings;
    1080  settings = gtk_settings_get_default();
    1081  g_object_set(settings, "gtk-application-prefer-dark-theme", remmina_pref.dark_theme, NULL);
    1083  gtk_toggle_button_set_active(remminamain->search_toggle, FALSE);
    1084  }
    1085  else{
    1086  gtk_toggle_button_set_active(remminamain->search_toggle, TRUE);
    1087  }
    1088  gtk_tree_view_column_set_visible(remminamain->column_files_list_notes, remmina_pref.always_show_notes);
    1089 }
    1090 
    1091 void remmina_main_on_action_application_preferences(GSimpleAction *action, GVariant *param, gpointer data)
    1092 {
    1093  TRACE_CALL(__func__);
    1094 
    1095  REMMINA_DEBUG("Opening the preferences");
    1096  gint32 tab_num;
    1097 
    1098  if (param) {
    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);
    1102  } else {
    1103  tab_num = 0;
    1104  }
    1105 
    1106  if (remmina_pref_get_boolean("use_primary_password")
    1107  && remmina_unlock_new(remminamain->window) == 0)
    1108  return;
    1109 
    1110  GtkWidget *widget = remmina_pref_dialog_new(tab_num, remminamain->window);
    1111 
    1112  gtk_widget_show_all(widget);
    1113 }
    1114 
    1115 void remmina_main_on_action_application_default(GSimpleAction *action, GVariant *param, gpointer data)
    1116 {
    1117  TRACE_CALL(__func__);
    1118 #ifndef __APPLE__
    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);
    1123  int i;
    1124 
    1125  desktop_info = g_desktop_app_info_new(id);
    1126  if (!desktop_info)
    1127  return;
    1128 
    1129  info = G_APP_INFO(desktop_info);
    1130 
    1131  for (i = 0; supported_mime_types[i]; i++) {
    1132  if (!g_app_info_set_as_default_for_type(info, supported_mime_types[i], &error))
    1133  g_warning("Failed to set '%s' as the default application for secondary content type '%s': %s",
    1134  g_app_info_get_name(info), supported_mime_types[i], error->message);
    1135  else
    1136  g_debug("Set '%s' as the default application for '%s'",
    1137  g_app_info_get_name(info),
    1139  }
    1140 #endif
    1141 }
    1142 
    1143 void remmina_main_on_action_application_quit(GSimpleAction *action, GVariant *param, gpointer data)
    1144 {
    1145  // Called by quit signal in remmina_main.glade
    1146  TRACE_CALL(__func__);
    1147  g_debug("Quit intercept");
    1149 }
    1150 
    1152 {
    1155  gtk_entry_set_text(remminamain->entry_quick_connect_server, "");
    1158  }
    1159 }
    1160 
    1161 static void remmina_main_import_file_list(GSList *files)
    1162 {
    1163  TRACE_CALL(__func__);
    1164  GtkWidget *dlg;
    1165  GSList *element;
    1166  gchar *path;
    1167  RemminaFilePlugin *plugin;
    1168  GString *err;
    1169  RemminaFile *remminafile = NULL;
    1170  gboolean imported;
    1171 
    1172  err = g_string_new(NULL);
    1173  imported = FALSE;
    1174  for (element = files; element; element = element->next) {
    1175  path = (gchar *)element->data;
    1177  if (plugin && (remminafile = plugin->import_func(plugin, path)) != NULL && remmina_file_get_string(remminafile, "name")) {
    1178  remmina_file_generate_filename(remminafile);
    1179  remmina_file_save(remminafile);
    1180  imported = TRUE;
    1181  } else {
    1182  g_string_append(err, path);
    1183  g_string_append_c(err, '\n');
    1184  }
    1185  if (remminafile) {
    1186  remmina_file_free(remminafile);
    1187  remminafile = NULL;
    1188  }
    1189  g_free(path);
    1190  }
    1191  g_slist_free(files);
    1192  if (err->len > 0) {
    1193  // TRANSLATORS: The placeholder %s is an error message
    1194  dlg = gtk_message_dialog_new(remminamain->window, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
    1195  _("Unable to import:\n%s"), err->str);
    1196  g_signal_connect(G_OBJECT(dlg), "response", G_CALLBACK(gtk_widget_destroy), NULL);
    1197  gtk_widget_show(dlg);
    1198  }
    1199  g_string_free(err, TRUE);
    1200  if (imported)
    1202 }
    1203 
    1204 static void remmina_main_action_tools_import_on_response(GtkDialog *dialog, gint response_id, gpointer user_data)
    1205 {
    1206  TRACE_CALL(__func__);
    1207  GSList *files;
    1208 
    1209  if (response_id == GTK_RESPONSE_ACCEPT) {
    1210  files = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
    1212  }
    1213  gtk_widget_destroy(GTK_WIDGET(dialog));
    1214 }
    1215 
    1216 void remmina_main_on_action_tools_import(GSimpleAction *action, GVariant *param, gpointer data)
    1217 {
    1218  TRACE_CALL(__func__);
    1219  GtkWidget *dialog;
    1220 
    1221  dialog = gtk_file_chooser_dialog_new(_("Import"), remminamain->window, GTK_FILE_CHOOSER_ACTION_OPEN, "Import",
    1222  GTK_RESPONSE_ACCEPT, NULL);
    1223  gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
    1224  g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(remmina_main_action_tools_import_on_response), NULL);
    1225  gtk_widget_show(dialog);
    1226 }
    1227 
    1228 void remmina_main_on_action_tools_export(GSimpleAction *action, GVariant *param, gpointer data)
    1229 {
    1230  TRACE_CALL(__func__);
    1231  RemminaFilePlugin *plugin;
    1232  RemminaFile *remminafile;
    1233  GtkWidget *dialog;
    1234 
    1235  if (!remminamain->priv->selected_filename)
    1236  return;
    1237 
    1238  remminafile = remmina_file_load(remminamain->priv->selected_filename);
    1239  if (remminafile == NULL)
    1240  return;
    1241  plugin = remmina_plugin_manager_get_export_file_handler(remminafile);
    1242  if (plugin) {
    1243  dialog = gtk_file_chooser_dialog_new(plugin->export_hints, remminamain->window,
    1244  GTK_FILE_CHOOSER_ACTION_SAVE, _("_Save"), GTK_RESPONSE_ACCEPT, NULL);
    1245  if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT)
    1246  plugin->export_func(plugin, remminafile, gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog)));
    1247  gtk_widget_destroy(dialog);
    1248  } else {
    1249  dialog = gtk_message_dialog_new(remminamain->window, GTK_DIALOG_MODAL, GTK_MESSAGE_ERROR, GTK_BUTTONS_OK,
    1250  _("This protocol does not support exporting."));
    1251  g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(gtk_widget_destroy), NULL);
    1252  gtk_widget_show(dialog);
    1253  }
    1254  remmina_file_free(remminafile);
    1255 }
    1256 
    1257 void remmina_main_on_action_application_plugins(GSimpleAction *action, GVariant *param, gpointer data)
    1258 {
    1259  TRACE_CALL(__func__);
    1260  remmina_plugin_manager_show(remminamain->window);
    1261 }
    1262 
    1263 void remmina_main_on_action_application_dark_theme(GSimpleAction *action, GVariant *param, gpointer data)
    1264 {
    1265  TRACE_CALL(__func__);
    1266  GtkSettings *settings;
    1267 
    1268  settings = gtk_settings_get_default();
    1269 
    1270  if (gtk_switch_get_active(remminamain->switch_dark_mode))
    1272  else
    1275 
    1276  g_object_set(settings, "gtk-application-prefer-dark-theme", remmina_pref.dark_theme, NULL);
    1277 }
    1278 
    1279 void remmina_main_on_action_help_homepage(GSimpleAction *action, GVariant *param, gpointer data)
    1280 {
    1281  TRACE_CALL(__func__);
    1282  g_app_info_launch_default_for_uri("https://www.remmina.org", NULL, NULL);
    1283 }
    1284 
    1285 void remmina_main_on_action_help_wiki(GSimpleAction *action, GVariant *param, gpointer data)
    1286 {
    1287  TRACE_CALL(__func__);
    1288  g_app_info_launch_default_for_uri("https://gitlab.com/Remmina/Remmina/wikis/home", NULL, NULL);
    1289 }
    1290 
    1291 void remmina_main_on_action_help_community(GSimpleAction *action, GVariant *param, gpointer data)
    1292 {
    1293  TRACE_CALL(__func__);
    1294  g_app_info_launch_default_for_uri("https://remmina.org/community", NULL, NULL);
    1295 }
    1296 
    1297 void remmina_main_on_action_help_donations(GSimpleAction *action, GVariant *param, gpointer data)
    1298 {
    1299  TRACE_CALL(__func__);
    1300  g_app_info_launch_default_for_uri("https://www.remmina.org/donations", NULL, NULL);
    1301 }
    1302 
    1303 void remmina_main_on_action_help_debug(GSimpleAction *action, GVariant *param, gpointer data)
    1304 {
    1305  TRACE_CALL(__func__);
    1307 }
    1308 
    1309 void remmina_main_on_action_application_about(GSimpleAction *action, GVariant *param, gpointer data)
    1310 {
    1311  TRACE_CALL(__func__);
    1312  remmina_about_open(remminamain->window);
    1313 };
    1314 
    1315 static gboolean is_empty(const gchar *s)
    1316 {
    1317  if (s == NULL)
    1318  return TRUE;
    1319  while (*s != 0) {
    1320  if (!isspace((unsigned char)*s))
    1321  return FALSE;
    1322  s++;
    1323  }
    1324  return TRUE;
    1325 }
    1326 
    1327 static gboolean remmina_main_quickconnect(void)
    1328 {
    1329  TRACE_CALL(__func__);
    1330  RemminaFile *remminafile;
    1331  gchar *server;
    1332  gchar *server_trimmed;
    1333  gchar *qcp;
    1334 
    1335 
    1336  /* Save quick connect protocol if different from the previous one */
    1337  qcp = gtk_combo_box_text_get_active_text(remminamain->combo_quick_connect_protocol);
    1338  if (qcp && strcmp(qcp, remmina_pref.last_quickconnect_protocol) != 0) {
    1340  remmina_pref.last_quickconnect_protocol = g_strdup(qcp);
    1342  }
    1343 
    1344  remminafile = remmina_file_new();
    1345  server = g_strdup(gtk_entry_get_text(remminamain->entry_quick_connect_server));
    1346  if (g_hostname_to_ascii(server) == NULL)
    1347  return FALSE;
    1348  /* If server contain /, e.g. vnc://, it won't connect
    1349  * We could search for an array of invalid characters, but
    1350  * it's better to find a way to correctly parse and validate addresses
    1351  */
    1352  if (g_strrstr(server, "/") != NULL)
    1353  return FALSE;
    1354  //if (g_str_has_suffix (server, "/"))
    1355  //return FALSE;
    1356  if (is_empty(server))
    1357  return FALSE;
    1358 
    1359  /* check if server is an IP address and trim whitespace if so */
    1360  server_trimmed = g_strdup(server);
    1361  g_strstrip(server_trimmed);
    1362  gchar **strings = g_strsplit(server_trimmed, ":", 2);
    1363 
    1364  if (strings[0] != NULL)
    1365  if (g_hostname_is_ip_address(strings[0]))
    1366  g_stpcpy(server, server_trimmed);
    1367 
    1368  remmina_file_set_string(remminafile, "sound", "off");
    1369  remmina_file_set_string(remminafile, "server", server);
    1370  remmina_file_set_string(remminafile, "name", server);
    1371  remmina_file_set_string(remminafile, "protocol", qcp);
    1372  g_free(server);
    1373  g_free(server_trimmed);
    1374  g_free(qcp);
    1375 
    1376  rcw_open_from_file(remminafile);
    1377 
    1378  return FALSE;
    1379 }
    1380 
    1381 gboolean remmina_main_quickconnect_on_click(GtkWidget *widget, gpointer user_data)
    1382 {
    1383  TRACE_CALL(__func__);
    1384  if (!kioskmode && kioskmode == FALSE)
    1385  return remmina_main_quickconnect();
    1386  return FALSE;
    1387 }
    1388 
    1389 /* Select all the text inside the quick search box if there is anything */
    1390 void remmina_main_quick_search_enter(GtkWidget *widget, gpointer user_data)
    1391 {
    1392  if (gtk_entry_get_text(remminamain->entry_quick_connect_server))
    1393  gtk_editable_select_region(GTK_EDITABLE(remminamain->entry_quick_connect_server), 0, -1);
    1394 }
    1395 
    1396 void remmina_main_on_action_collapse(GSimpleAction *action, GVariant *param, gpointer data)
    1397 {
    1398  TRACE_CALL(__func__);
    1399  gtk_tree_view_collapse_all(remminamain->tree_files_list);
    1400 }
    1401 
    1402 void remmina_main_on_action_search_toggle(GSimpleAction *action, GVariant *param, gpointer data)
    1403 {
    1404  TRACE_CALL(__func__);
    1405  REMMINA_DEBUG("Search toggle triggered");
    1406 
    1407  gboolean toggle_status = gtk_toggle_button_get_active(remminamain->search_toggle);
    1408 
    1409  gtk_search_bar_set_search_mode(remminamain->search_bar, toggle_status);
    1410  if (toggle_status) {
    1411  REMMINA_DEBUG("Search toggle is active");
    1412  gtk_widget_grab_focus(GTK_WIDGET(remminamain->entry_quick_connect_server));
    1413  } else {
    1414  REMMINA_DEBUG("Search toggle is not active, focus is tree_files_list");
    1415  gtk_widget_grab_focus(GTK_WIDGET(remminamain->tree_files_list));
    1416  }
    1417 }
    1418 
    1420 {
    1421  TRACE_CALL(__func__);
    1422  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(remminamain->search_toggle), TRUE);
    1423 }
    1424 
    1425 void remmina_main_on_action_expand(GSimpleAction *action, GVariant *param, gpointer data)
    1426 {
    1427  TRACE_CALL(__func__);
    1428  gtk_tree_view_expand_all(remminamain->tree_files_list);
    1429 }
    1430 
    1431 /* Handle double click on a row in the connections list */
    1432 void remmina_main_file_list_on_row_activated(GtkTreeView *tree, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data)
    1433 {
    1434  TRACE_CALL(__func__);
    1435 /* If a connection was selected then execute the default action */
    1436  if (remminamain->priv->selected_filename) {
    1437  switch (remmina_pref.default_action) {
    1438  case REMMINA_ACTION_EDIT:
    1439  remmina_main_on_action_connection_edit(NULL, NULL, NULL);
    1440  break;
    1442  default:
    1444  break;
    1445  }
    1446  }
    1447 }
    1448 
    1449 /* Show the popup menu by the right button mouse click */
    1450 gboolean remmina_main_file_list_on_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
    1451 {
    1452  TRACE_CALL(__func__);
    1453  if (event->button == MOUSE_BUTTON_RIGHT) {
    1454  if (!kioskmode && kioskmode == FALSE) {
    1455 #if GTK_CHECK_VERSION(3, 22, 0)
    1456  // For now, if more than one selected row, display only a delete menu option
    1457  if (gtk_tree_selection_count_selected_rows(gtk_tree_view_get_selection(remminamain->tree_files_list)) > 1) {
    1458  gtk_menu_popup_at_pointer(GTK_MENU(remminamain->menu_popup_delete_rc), (GdkEvent *)event);
    1459  return GDK_EVENT_STOP;
    1460  }
    1461  else {
    1462  gtk_menu_popup_at_pointer(GTK_MENU(remminamain->menu_popup), (GdkEvent *)event);
    1463  }
    1464 #else
    1465  gtk_menu_popup(remminamain->menu_popup, NULL, NULL, NULL, NULL, event->button, event->time);
    1466 #endif
    1467  }
    1468  }
    1469  return FALSE;
    1470 }
    1471 
    1472 /* Show the popup menu by the menu key */
    1473 gboolean remmina_main_file_list_on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
    1474 {
    1475  TRACE_CALL(__func__);
    1476  if (event->keyval == GDK_KEY_Menu) {
    1477 #if GTK_CHECK_VERSION(3, 22, 0)
    1478  gtk_menu_popup_at_widget(GTK_MENU(remminamain->menu_popup), widget,
    1479  GDK_GRAVITY_CENTER, GDK_GRAVITY_CENTER,
    1480  (GdkEvent *)event);
    1481 #else
    1482  gtk_menu_popup(remminamain->menu_popup, NULL, NULL, NULL, NULL, 0, event->time);
    1483 #endif
    1484  }
    1485  return FALSE;
    1486 }
    1487 
    1488 void remmina_main_quick_search_on_icon_press(GtkEntry *entry, GtkEntryIconPosition icon_pos, GdkEvent *event, gpointer user_data)
    1489 {
    1490  TRACE_CALL(__func__);
    1491  if (icon_pos == GTK_ENTRY_ICON_SECONDARY)
    1492  gtk_entry_set_text(entry, "");
    1493 }
    1494 
    1495 void remmina_main_quick_search_on_changed(GtkEditable *editable, gpointer user_data)
    1496 {
    1497  TRACE_CALL(__func__);
    1498  /* If a search text was input then temporary set the file mode to list */
    1499  if (gtk_entry_get_text_length(remminamain->entry_quick_connect_server)) {
    1500  if (GTK_IS_TREE_STORE(remminamain->priv->file_model)) {
    1501  /* File view mode changed, put it to override and reload list */
    1502  remminamain->priv->override_view_file_mode_to_list = TRUE;
    1504  }
    1505  } else {
    1506  if (remminamain->priv->override_view_file_mode_to_list) {
    1507  /* File view mode changed, put it to default (disable override) and reload list */
    1508  remminamain->priv->override_view_file_mode_to_list = FALSE;
    1510  }
    1511  }
    1512  gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(remminamain->priv->file_model_filter));
    1513 }
    1514 
    1515 void remmina_main_on_drag_data_received(GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y,
    1516  GtkSelectionData *data, guint info, guint time, gpointer user_data)
    1517 {
    1518  TRACE_CALL(__func__);
    1519  gchar **uris;
    1520  GSList *files = NULL;
    1521  gint i;
    1522 
    1523  uris = g_uri_list_extract_uris((const gchar *)gtk_selection_data_get_data(data));
    1524  for (i = 0; uris[i]; i++) {
    1525  if (strncmp(uris[i], "file://", 7) != 0)
    1526  continue;
    1527  files = g_slist_append(files, g_strdup(uris[i] + 7));
    1528  }
    1529  g_strfreev(uris);
    1531 }
    1532 
    1533 /* Add a new menuitem to the Tools menu */
    1534 static gboolean remmina_main_add_tool_plugin(gchar *name, RemminaPlugin *plugin, gpointer user_data)
    1535 {
    1536  TRACE_CALL(__func__);
    1537  RemminaToolPlugin *tool_plugin = (RemminaToolPlugin *)plugin;
    1538  GtkWidget *menuitem = gtk_menu_item_new_with_label(plugin->description);
    1539 
    1540  gtk_widget_show(menuitem);
    1541  gtk_menu_shell_append(GTK_MENU_SHELL(remminamain->menu_popup_full), menuitem);
    1542  g_signal_connect(G_OBJECT(menuitem), "activate", G_CALLBACK(tool_plugin->exec_func), tool_plugin);
    1543  return FALSE;
    1544 }
    1545 
    1546 gboolean remmina_main_on_window_state_event(GtkWidget *widget, GdkEventWindowState *event, gpointer user_data)
    1547 {
    1548  TRACE_CALL(__func__);
    1549  return FALSE;
    1550 }
    1551 
    1552 /* Remmina main window initialization */
    1553 static void remmina_main_init(void)
    1554 {
    1555  TRACE_CALL(__func__);
    1556  int i, qcp_idx, qcp_actidx;
    1557  char *name;
    1558  GtkSettings *settings;
    1559 
    1560  REMMINA_DEBUG("Initializing the Remmina main window");
    1561  /* Switch to a dark theme if the user enabled it */
    1562  settings = gtk_settings_get_default();
    1563  g_object_set(settings, "gtk-application-prefer-dark-theme", remmina_pref.dark_theme, NULL);
    1564 
    1565  REMMINA_DEBUG ("Initializing monitor");
    1566  remminamain->monitor = remmina_network_monitor_new();
    1567 
    1569  if (!kioskmode && kioskmode == FALSE)
    1570  gtk_window_set_title(remminamain->window, _("Remmina Remote Desktop Client"));
    1571  else
    1572  gtk_window_set_title(remminamain->window, _("Remmina Kiosk"));
    1573  if (!kioskmode && kioskmode == FALSE) {
    1574  gtk_window_set_default_size(remminamain->window, remmina_pref.main_width, remmina_pref.main_height);
    1576  gtk_window_maximize(remminamain->window);
    1577  }
    1578  /* Honor global preferences Search Bar visibility */
    1580  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(RM_GET_OBJECT("search_toggle")), FALSE);
    1581 
    1582  /* Add a GtkMenuItem to the Tools menu for each plugin of type REMMINA_PLUGIN_TYPE_TOOL */
    1584 
    1585  /* Add available quick connect protocols to remminamain->combo_quick_connect_protocol */
    1586  qcp_idx = qcp_actidx = 0;
    1587  for (i = 0; i < sizeof(quick_connect_plugin_list) / sizeof(quick_connect_plugin_list[0]); i++) {
    1588  name = quick_connect_plugin_list[i];
    1590  gtk_combo_box_text_append(remminamain->combo_quick_connect_protocol, name, name);
    1592  qcp_actidx = qcp_idx;
    1593  qcp_idx++;
    1594  }
    1595  }
    1596  gtk_combo_box_set_active(GTK_COMBO_BOX(remminamain->combo_quick_connect_protocol), qcp_actidx);
    1597 
    1598  /* Connect the group accelerators to the GtkWindow */
    1599  //gtk_window_add_accel_group(remminamain->window, remminamain->accelgroup_shortcuts);
    1600  /* Set the Quick Connection */
    1601  gtk_entry_set_activates_default(remminamain->entry_quick_connect_server, TRUE);
    1602  /* Set the TreeView for the files list */
    1603  gtk_tree_selection_set_select_function(
    1604  gtk_tree_view_get_selection(remminamain->tree_files_list),
    1605  remmina_main_selection_func, NULL, NULL);
    1607  gtk_tree_view_set_search_entry(remminamain->tree_files_list, GTK_ENTRY(remminamain->entry_quick_connect_server));
    1609  gtk_widget_grab_focus(GTK_WIDGET(remminamain->tree_files_list));
    1610  /* Load the files list */
    1612 
    1613  /* Drag-n-drop support */
    1614  gtk_drag_dest_set(GTK_WIDGET(remminamain->window), GTK_DEST_DEFAULT_ALL, remmina_drop_types, 1, GDK_ACTION_COPY);
    1615 
    1616  /* Finish initialization */
    1617  remminamain->priv->initialized = TRUE;
    1618 
    1619  /* Register the window in remmina_widget_pool with GType=GTK_WINDOW and TAG=remmina-main-window */
    1620  g_object_set_data(G_OBJECT(remminamain->window), "tag", "remmina-main-window");
    1621  remmina_widget_pool_register(GTK_WIDGET(remminamain->window));
    1622 }
    1623 
    1624 /* Signal handler for "show" on remminamain->window */
    1625 void remmina_main_on_show(GtkWidget *w, gpointer user_data)
    1626 {
    1627  TRACE_CALL(__func__);
    1628 #ifdef SNAP_BUILD
    1630 #endif
    1631 }
    1632 
    1633 /* RemminaMain instance */
    1634 GtkWidget *remmina_main_new(void)
    1635 {
    1636  TRACE_CALL(__func__);
    1637  GSimpleActionGroup *actions;
    1638  GtkAccelGroup *accel_group = NULL;
    1639 
    1640  remminamain = g_new0(RemminaMain, 1);
    1641  remminamain->priv = g_new0(RemminaMainPriv, 1);
    1642  /* Assign UI widgets to the private members */
    1643  remminamain->builder = remmina_public_gtk_builder_new_from_resource("/org/remmina/Remmina/src/../data/ui/remmina_main.glade");
    1644  remminamain->window = GTK_WINDOW(RM_GET_OBJECT("RemminaMain"));
    1645  if (kioskmode && kioskmode == TRUE) {
    1646  gtk_window_set_position(remminamain->window, GTK_WIN_POS_CENTER_ALWAYS);
    1647  gtk_window_set_default_size(remminamain->window, 800, 400);
    1648  gtk_window_set_resizable(remminamain->window, FALSE);
    1649  }
    1650  /* New Button */
    1651  remminamain->button_new = GTK_BUTTON(RM_GET_OBJECT("button_new"));
    1652  if (kioskmode && kioskmode == TRUE)
    1653  gtk_widget_set_sensitive(GTK_WIDGET(remminamain->button_new), FALSE);
    1654  /* Search bar */
    1655  remminamain->search_toggle = GTK_TOGGLE_BUTTON(RM_GET_OBJECT("search_toggle"));
    1656  remminamain->search_bar = GTK_SEARCH_BAR(RM_GET_OBJECT("search_bar"));
    1657  /* view mode list/tree */
    1658  remminamain->view_toggle_button = GTK_TOGGLE_BUTTON(RM_GET_OBJECT("view_toggle_button"));
    1659  if (kioskmode && kioskmode == TRUE)
    1660  gtk_widget_set_sensitive(GTK_WIDGET(remminamain->view_toggle_button), FALSE);
    1661 
    1662  /* Menu widgets */
    1663  remminamain->menu_popup = GTK_MENU(RM_GET_OBJECT("menu_popup"));
    1664  remminamain->menu_header_button = GTK_MENU_BUTTON(RM_GET_OBJECT("menu_header_button"));
    1665  remminamain->menu_popup_full = GTK_MENU(RM_GET_OBJECT("menu_popup_full"));
    1666  remminamain->menu_popup_delete_rc = GTK_MENU(RM_GET_OBJECT("menu_popup_delete_rc"));
    1667  if (kioskmode && kioskmode == TRUE) {
    1668  gtk_widget_set_sensitive(GTK_WIDGET(remminamain->menu_popup_full), FALSE);
    1669  gtk_widget_set_sensitive(GTK_WIDGET(remminamain->menu_header_button), FALSE);
    1670  }
    1671  /* View mode radios */
    1672  remminamain->menuitem_view_mode_list = GTK_RADIO_MENU_ITEM(RM_GET_OBJECT("menuitem_view_mode_list"));
    1673  remminamain->menuitem_view_mode_tree = GTK_RADIO_MENU_ITEM(RM_GET_OBJECT("menuitem_view_mode_tree"));
    1674  /* Quick connect objects */
    1675  remminamain->box_quick_connect = GTK_BOX(RM_GET_OBJECT("box_quick_connect"));
    1676  remminamain->combo_quick_connect_protocol = GTK_COMBO_BOX_TEXT(RM_GET_OBJECT("combo_quick_connect_protocol"));
    1677  if (kioskmode && kioskmode == TRUE)
    1678  gtk_widget_set_sensitive(GTK_WIDGET(remminamain->combo_quick_connect_protocol), FALSE);
    1679  remminamain->entry_quick_connect_server = GTK_ENTRY(RM_GET_OBJECT("entry_quick_connect_server"));
    1680  /* Other widgets */
    1681  remminamain->tree_files_list = GTK_TREE_VIEW(RM_GET_OBJECT("tree_files_list"));
    1682  remminamain->column_files_list_name = GTK_TREE_VIEW_COLUMN(RM_GET_OBJECT("column_files_list_name"));
    1683  remminamain->column_files_list_group = GTK_TREE_VIEW_COLUMN(RM_GET_OBJECT("column_files_list_group"));
    1684  remminamain->column_files_list_server = GTK_TREE_VIEW_COLUMN(RM_GET_OBJECT("column_files_list_server"));
    1685  remminamain->column_files_list_plugin = GTK_TREE_VIEW_COLUMN(RM_GET_OBJECT("column_files_list_plugin"));
    1686  remminamain->column_files_list_date = GTK_TREE_VIEW_COLUMN(RM_GET_OBJECT("column_files_list_date"));
    1687  remminamain->column_files_list_notes = GTK_TREE_VIEW_COLUMN(RM_GET_OBJECT("column_files_list_notes"));
    1688  gtk_tree_view_column_set_fixed_width(remminamain->column_files_list_notes, 100);
    1689  remminamain->statusbar_main = GTK_STATUSBAR(RM_GET_OBJECT("statusbar_main"));
    1690  /* signals */
    1691  g_signal_connect(remminamain->entry_quick_connect_server, "key-release-event", G_CALLBACK(remmina_main_search_key_event), NULL);
    1692  g_signal_connect(remminamain->tree_files_list, "row-activated", G_CALLBACK(remmina_main_tree_row_activated), NULL);
    1693  /* Non widget objects */
    1694  actions = g_simple_action_group_new();
    1695  g_action_map_add_action_entries(G_ACTION_MAP(actions), app_actions, G_N_ELEMENTS(app_actions), remminamain->window);
    1696  gtk_widget_insert_action_group(GTK_WIDGET(remminamain->window), "app", G_ACTION_GROUP(actions));
    1697  g_action_map_add_action_entries(G_ACTION_MAP(actions), main_actions, G_N_ELEMENTS(main_actions), remminamain->window);
    1698  gtk_widget_insert_action_group(GTK_WIDGET(remminamain->window), "main", G_ACTION_GROUP(actions));
    1699  g_object_unref(actions);
    1700  /* Accelerators */
    1701  accel_group = gtk_accel_group_new();
    1702  gtk_window_add_accel_group(remminamain->window, accel_group);
    1703  gtk_accel_group_connect(accel_group, GDK_KEY_Q, GDK_CONTROL_MASK, 0,
    1704  g_cclosure_new_swap(G_CALLBACK(remmina_main_on_action_application_quit), NULL, NULL));
    1705  // TODO: This crash remmina because the function doesn't receive the parameter we expect
    1706  gtk_accel_group_connect(accel_group, GDK_KEY_P, GDK_CONTROL_MASK, 0,
    1707  g_cclosure_new_swap(G_CALLBACK(remmina_main_on_accel_application_preferences), NULL, NULL));
    1708  gtk_accel_group_connect(accel_group, GDK_KEY_F, GDK_CONTROL_MASK, 0,
    1709  g_cclosure_new_swap(G_CALLBACK(remmina_main_on_accel_search_toggle), remminamain, NULL));
    1710 
    1711  /* Connect signals */
    1712  gtk_builder_connect_signals(remminamain->builder, NULL);
    1713  /* Initialize the window and load the preferences */
    1715  return GTK_WIDGET(remminamain->window);
    1716 }
    1717 
    1719 {
    1720  if (!remminamain)
    1721  return NULL;
    1722  if (!remminamain->priv)
    1723  return NULL;
    1724  if (!remminamain->priv->initialized)
    1725  return NULL;
    1726  remminamain->window = GTK_WINDOW(RM_GET_OBJECT("RemminaMain"));
    1727  return remminamain->window;
    1728 }
    1729 
    1731 {
    1732  if (!remminamain)
    1733  return;
    1735 }
    1736 
    1737 void remmina_main_show_dialog(GtkMessageType msg, GtkButtonsType buttons, const gchar* message) {
    1738  GtkWidget *dialog;
    1739 
    1740  if (remminamain->window) {
    1741  dialog = gtk_message_dialog_new(remminamain->window, GTK_DIALOG_MODAL, msg, buttons, "%s", message);
    1742  gtk_dialog_run(GTK_DIALOG(dialog));
    1743  gtk_widget_destroy(dialog);
    1744  }
    1745 }
    1746 
    1747 void remmina_main_show_warning_dialog(const gchar *message) {
    1748  GtkWidget *dialog;
    1749 
    1750  if (remminamain->window) {
    1751  dialog = gtk_message_dialog_new(remminamain->window, GTK_DIALOG_MODAL, GTK_MESSAGE_WARNING, GTK_BUTTONS_CLOSE,
    1752  message, g_get_application_name());
    1753  gtk_dialog_run(GTK_DIALOG(dialog));
    1754  gtk_widget_destroy(dialog);
    1755  }
    1756 }
    G_BEGIN_DECLS struct _RemminaGroupData RemminaGroupData
    +Go to the documentation of this file.
    1 /*
    2  * Remmina - The GTK+ Remote Desktop Client
    3  * Copyright (C) 2009-2011 Vic Lee
    4  * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
    5  * Copyright (C) 2016-2022 Antenore Gatta, Giovanni Panozzo
    6  * Copyright (C) 2022-2023 Antenore Gatta, Giovanni Panozzo, Hiroyuki Tanaka
    7  *
    8  * This program is free software; you can redistribute it and/or modify
    9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    16  * GNU General Public License for more details.
    17  *
    18  * You should have received a copy of the GNU General Public License
    19  * along with this program; if not, write to the Free Software
    20  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
    21  * Boston, MA 02110-1301, USA.
    22  *
    23  * In addition, as a special exception, the copyright holders give
    24  * permission to link the code of portions of this program with the
    25  * OpenSSL library under certain conditions as described in each
    26  * individual source file, and distribute linked combinations
    27  * including the two.
    28  * You must obey the GNU General Public License in all respects
    29  * for all of the code used other than OpenSSL. * If you modify
    30  * file(s) with this exception, you may extend this exception to your
    31  * version of the file(s), but you are not obligated to do so. * If you
    32  * do not wish to do so, delete this exception statement from your
    33  * version. * If you delete this exception statement from all source
    34  * files in the program, then also delete it here.
    35  *
    36  */
    37 
    38 #include "config.h"
    39 #include <ctype.h>
    40 #include <gio/gio.h>
    41 #ifndef __APPLE__
    42 #include <gio/gdesktopappinfo.h>
    43 #endif
    44 #include <gdk/gdkkeysyms.h>
    45 #include <glib/gi18n.h>
    46 #include <gtk/gtk.h>
    47 
    48 #include "remmina.h"
    49 #include "remmina_string_array.h"
    50 #include "remmina_public.h"
    51 #include "remmina_file.h"
    52 #include "remmina_file_manager.h"
    53 #include "remmina_file_editor.h"
    54 #include "rcw.h"
    55 #include "remmina_about.h"
    56 #include "remmina_pref.h"
    57 #include "remmina_pref_dialog.h"
    58 #include "remmina_widget_pool.h"
    59 #include "remmina_plugin_manager.h"
    60 #include "remmina_log.h"
    61 #include "remmina_icon.h"
    62 #include "remmina_main.h"
    63 #include "remmina_exec.h"
    64 #include "remmina_mpchange.h"
    65 #include "remmina_external_tools.h"
    66 #include "remmina_unlock.h"
    68 
    70 
    71 #define RM_GET_OBJECT(object_name) gtk_builder_get_object(remminamain->builder, object_name)
    72 
    73 enum {
    84 };
    85 
    86 static
    87 const gchar *supported_mime_types[] = {
    88  "x-scheme-handler/rdp",
    89  "x-scheme-handler/spice",
    90  "x-scheme-handler/vnc",
    91  "x-scheme-handler/remmina",
    92  "application/x-remmina",
    93  NULL
    94 };
    95 
    96 static GActionEntry app_actions[] = {
    97  { "about", remmina_main_on_action_application_about, NULL, NULL, NULL },
    98  { "default", remmina_main_on_action_application_default, NULL, NULL, NULL },
    99  { "mpchange", remmina_main_on_action_application_mpchange, NULL, NULL, NULL },
    100  { "plugins", remmina_main_on_action_application_plugins, NULL, NULL, NULL },
    101  { "preferences", remmina_main_on_action_application_preferences, "i", NULL, NULL },
    102  { "dark", remmina_main_on_action_application_dark_theme, NULL, NULL, NULL },
    103  { "debug", remmina_main_on_action_help_debug, NULL, NULL, NULL },
    104  { "community", remmina_main_on_action_help_community, NULL, NULL, NULL },
    105  { "donations", remmina_main_on_action_help_donations, NULL, NULL, NULL },
    106  { "homepage", remmina_main_on_action_help_homepage, NULL, NULL, NULL },
    107  { "wiki", remmina_main_on_action_help_wiki, NULL, NULL, NULL },
    108  { "quit", remmina_main_on_action_application_quit, NULL, NULL, NULL },
    109 };
    110 
    111 static GActionEntry main_actions[] = {
    112  { "connect", remmina_main_on_action_connection_connect, NULL, NULL, NULL },
    113  { "copy", remmina_main_on_action_connection_copy, NULL, NULL, NULL },
    114  { "delete", remmina_main_on_action_connection_delete, NULL, NULL, NULL },
    115  { "delete_multiple", remmina_main_on_action_connection_delete_multiple, NULL, NULL, NULL },
    116  { "edit", remmina_main_on_action_connection_edit, NULL, NULL, NULL },
    117  { "exttools", remmina_main_on_action_connection_external_tools, NULL, NULL, NULL },
    118  { "new", remmina_main_on_action_connection_new, NULL, NULL, NULL },
    119  { "export", remmina_main_on_action_tools_export, NULL, NULL, NULL },
    120  { "import", remmina_main_on_action_tools_import, NULL, NULL, NULL },
    121  { "expand", remmina_main_on_action_expand, NULL, NULL, NULL },
    122  { "collapse", remmina_main_on_action_collapse, NULL, NULL, NULL },
    123  { "search", remmina_main_on_action_search_toggle, NULL, NULL, NULL },
    124 };
    125 
    126 static GtkTargetEntry remmina_drop_types[] =
    127 {
    128  { "text/uri-list", 0, 1 }
    129 };
    130 
    132 {
    133  "RDP", "VNC", "SSH", "NX", "SPICE", "X2GO"
    134 };
    135 
    139 static void remmina_main_save_size(void)
    140 {
    141  TRACE_CALL(__func__);
    142  if ((gdk_window_get_state(gtk_widget_get_window(GTK_WIDGET(remminamain->window))) & GDK_WINDOW_STATE_MAXIMIZED) == 0) {
    143  gtk_window_get_size(remminamain->window, &remmina_pref.main_width, &remmina_pref.main_height);
    144  remmina_pref.main_maximize = FALSE;
    145  } else {
    147  }
    148 }
    149 
    150 static void remmina_main_save_expanded_group_func(GtkTreeView *tree_view, GtkTreePath *path, gpointer user_data)
    151 {
    152  TRACE_CALL(__func__);
    153  GtkTreeIter iter;
    154  gchar *group;
    155 
    156  gtk_tree_model_get_iter(remminamain->priv->file_model_sort, &iter, path);
    157  gtk_tree_model_get(remminamain->priv->file_model_sort, &iter, GROUP_COLUMN, &group, -1);
    158  if (group) {
    159  remmina_string_array_add(remminamain->priv->expanded_group, group);
    160  g_free(group);
    161  }
    162 }
    163 
    165 {
    166  TRACE_CALL(__func__);
    167  if (GTK_IS_TREE_STORE(remminamain->priv->file_model)) {
    168  if (remminamain->priv->expanded_group)
    170  remminamain->priv->expanded_group = remmina_string_array_new();
    171  gtk_tree_view_map_expanded_rows(remminamain->tree_files_list,
    172  (GtkTreeViewMappingFunc)remmina_main_save_expanded_group_func, NULL);
    173  }
    174 }
    175 
    181 {
    182  TRACE_CALL(__func__);
    183  if (!remminamain || !remminamain->window)
    184  return;
    185 
    191 }
    192 
    194 {
    195  TRACE_CALL(__func__);
    196 
    197  if (remminamain) {
    198  if (remminamain->window)
    199  gtk_widget_destroy(GTK_WIDGET(remminamain->window));
    200 
    201  g_object_unref(remminamain->builder);
    203  remminamain->priv->expanded_group = NULL;
    204  if (remminamain->priv->file_model)
    205  g_object_unref(G_OBJECT(remminamain->priv->file_model));
    206  g_object_unref(G_OBJECT(remminamain->priv->file_model_filter));
    207  g_free(remminamain->priv->selected_filename);
    208  g_free(remminamain->priv->selected_name);
    209  g_free(remminamain->priv);
    210  g_free(remminamain);
    211  remminamain = NULL;
    212  }
    213 }
    214 
    218 static gboolean remmina_main_dexit(gpointer data)
    219 {
    220  TRACE_CALL(__func__);
    222  return FALSE;
    223 }
    224 
    225 gboolean remmina_main_on_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
    226 {
    227  TRACE_CALL(__func__);
    229 
    230  g_idle_add(remmina_main_dexit, NULL);
    231 
    232  return FALSE;
    233 }
    234 
    235 gboolean remmina_main_idle_destroy(gpointer data)
    236 {
    237  TRACE_CALL(__func__);
    238 
    239  if (remminamain)
    241 
    242  return G_SOURCE_REMOVE;
    243 }
    244 
    249 {
    250  TRACE_CALL(__func__);
    251 
    252  if (remminamain) {
    253  /* Invalidate remminamain->window to avoid multiple destructions */
    254  remminamain->window = NULL;
    255  /* Destroy remminamain struct, later. We can't destroy
    256  * important objects like the builder now */
    257  g_idle_add(remmina_main_idle_destroy, NULL);
    258  }
    259 }
    260 
    262 {
    263  TRACE_CALL(__func__);
    264  g_free(remminamain->priv->selected_filename);
    265  g_free(remminamain->priv->selected_name);
    266  remminamain->priv->selected_filename = NULL;
    267  remminamain->priv->selected_name = NULL;
    268 }
    269 
    270 #ifdef SNAP_BUILD
    271 
    273 {
    274  GtkBuilder *dlgbuilder = NULL;
    275  GtkWidget *dlg;
    276  GtkWindow *parent;
    277  int result;
    278  static gboolean shown_once = FALSE;
    279  gboolean need_snap_interface_connections = FALSE;
    280  GtkWidget *dsa;
    282 
    283  if (shown_once)
    284  return;
    285  else
    286  shown_once = TRUE;
    287 
    288  g_print("Remmina is compiled as a SNAP package.\n");
    289  remmina_secret_plugin = remmina_plugin_manager_get_secret_plugin();
    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;
    293  } else {
    294  if (!remmina_secret_plugin->is_service_available(remmina_secret_plugin)) {
    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;
    297  }
    298  }
    299 
    300  if (need_snap_interface_connections && !remmina_pref.prevent_snap_welcome_message) {
    301  dlgbuilder = remmina_public_gtk_builder_new_from_resource("/org/remmina/Remmina/src/../data/ui/remmina_snap_info_dialog.glade");
    302  dsa = GTK_WIDGET(gtk_builder_get_object(dlgbuilder, "dontshowagain"));
    303  if (dlgbuilder) {
    304  parent = remmina_main_get_window();
    305  dlg = GTK_WIDGET(gtk_builder_get_object(dlgbuilder, "SnapInfoDlg"));
    306  if (parent)
    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));
    310  if (result == 1) {
    311  remmina_pref.prevent_snap_welcome_message = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(dsa));
    313  }
    314  gtk_widget_destroy(dlg);
    315  g_object_unref(dlgbuilder);
    316  }
    317  }
    318 }
    319 #endif
    320 
    321 
    322 static gboolean remmina_main_selection_func(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path,
    323  gboolean path_currently_selected, gpointer user_data)
    324 {
    325  TRACE_CALL(__func__);
    326  guint context_id;
    327  GtkTreeIter iter;
    328  gchar buf[1000];
    329 
    330  if (path_currently_selected)
    331  return TRUE;
    332 
    333  if (!gtk_tree_model_get_iter(model, &iter, path))
    334  return TRUE;
    335 
    337 
    338  gtk_tree_model_get(model, &iter,
    339  NAME_COLUMN, &remminamain->priv->selected_name,
    340  FILENAME_COLUMN, &remminamain->priv->selected_filename,
    341  -1);
    342 
    343  context_id = gtk_statusbar_get_context_id(remminamain->statusbar_main, "status");
    344  gtk_statusbar_pop(remminamain->statusbar_main, context_id);
    345  if (remminamain->priv->selected_filename) {
    346  g_snprintf(buf, sizeof(buf), "%s (%s)", remminamain->priv->selected_name, remminamain->priv->selected_filename);
    347  gtk_statusbar_push(remminamain->statusbar_main, context_id, buf);
    348  } else {
    349  gtk_statusbar_push(remminamain->statusbar_main, context_id, remminamain->priv->selected_name);
    350  }
    351 
    352  return TRUE;
    353 }
    354 
    355 static void remmina_main_load_file_list_callback(RemminaFile *remminafile, gpointer user_data)
    356 {
    357  TRACE_CALL(__func__);
    358  GtkTreeIter iter;
    359  GtkListStore *store;
    360 
    361  store = GTK_LIST_STORE(user_data);
    362  gchar *datetime;
    363 
    364  datetime = remmina_file_get_datetime(remminafile);
    365  gtk_list_store_append(store, &iter);
    366  gtk_list_store_set(store, &iter,
    368  NAME_COLUMN, remmina_file_get_string(remminafile, "name"),
    369  NOTES_COLUMN, g_uri_unescape_string(remmina_file_get_string(remminafile, "notes_text"), NULL),
    370  GROUP_COLUMN, remmina_file_get_string(remminafile, "group"),
    371  SERVER_COLUMN, remmina_file_get_string(remminafile, "server"),
    372  PLUGIN_COLUMN, remmina_file_get_string(remminafile, "protocol"),
    373  DATE_COLUMN, datetime,
    375  LABELS_COLUMN, remmina_file_get_string(remminafile, "labels"),
    376  -1);
    377  g_free(datetime);
    378 }
    379 
    380 static gboolean remmina_main_load_file_tree_traverse(GNode *node, GtkTreeStore *store, GtkTreeIter *parent)
    381 {
    382  TRACE_CALL(__func__);
    383  GtkTreeIter *iter;
    384  RemminaGroupData *data;
    385  GNode *child;
    386 
    387  iter = NULL;
    388  if (node->data) {
    389  data = (RemminaGroupData *)node->data;
    390  iter = g_new0(GtkTreeIter, 1);
    391  gtk_tree_store_append(store, iter, parent);
    392  gtk_tree_store_set(store, iter,
    393  PROTOCOL_COLUMN, "folder-symbolic",
    394  NAME_COLUMN, data->name,
    395  GROUP_COLUMN, data->group,
    396  DATE_COLUMN, data->datetime,
    397  FILENAME_COLUMN, NULL,
    398  LABELS_COLUMN, data->labels,
    399  -1);
    400  }
    401  for (child = g_node_first_child(node); child; child = g_node_next_sibling(child))
    402  remmina_main_load_file_tree_traverse(child, store, iter);
    403  g_free(iter);
    404  return FALSE;
    405 }
    406 
    407 static void remmina_main_load_file_tree_group(GtkTreeStore *store)
    408 {
    409  TRACE_CALL(__func__);
    410  GNode *root;
    411 
    413  remmina_main_load_file_tree_traverse(root, store, NULL);
    415 }
    416 
    417 static void remmina_main_expand_group_traverse(GtkTreeIter *iter)
    418 {
    419  TRACE_CALL(__func__);
    420  GtkTreeModel *tree;
    421  gboolean ret;
    422  gchar *group, *filename;
    423  GtkTreeIter child;
    424  GtkTreePath *path;
    425 
    426  tree = remminamain->priv->file_model_sort;
    427  ret = TRUE;
    428  while (ret) {
    429  gtk_tree_model_get(tree, iter, GROUP_COLUMN, &group, FILENAME_COLUMN, &filename, -1);
    430  if (filename == NULL) {
    431  if (remmina_string_array_find(remminamain->priv->expanded_group, group) >= 0) {
    432  path = gtk_tree_model_get_path(tree, iter);
    433  gtk_tree_view_expand_row(remminamain->tree_files_list, path, FALSE);
    434  gtk_tree_path_free(path);
    435  }
    436  if (gtk_tree_model_iter_children(tree, &child, iter))
    438  }
    439  g_free(group);
    440  g_free(filename);
    441 
    442  ret = gtk_tree_model_iter_next(tree, iter);
    443  }
    444 }
    445 
    446 static void remmina_main_expand_group(void)
    447 {
    448  TRACE_CALL(__func__);
    449  GtkTreeIter iter;
    450 
    451  if (gtk_tree_model_get_iter_first(remminamain->priv->file_model_sort, &iter))
    453 }
    454 
    455 static gboolean remmina_main_load_file_tree_find(GtkTreeModel *tree, GtkTreeIter *iter, const gchar *match_group)
    456 {
    457  TRACE_CALL(__func__);
    458  gboolean ret, match;
    459  gchar *group, *filename;
    460  GtkTreeIter child;
    461 
    462  match = FALSE;
    463  ret = TRUE;
    464  while (ret) {
    465  gtk_tree_model_get(tree, iter, GROUP_COLUMN, &group, FILENAME_COLUMN, &filename, -1);
    466  match = (filename == NULL && g_strcmp0(group, match_group) == 0);
    467  g_free(group);
    468  g_free(filename);
    469  if (match)
    470  break;
    471  if (gtk_tree_model_iter_children(tree, &child, iter)) {
    472  match = remmina_main_load_file_tree_find(tree, &child, match_group);
    473  if (match) {
    474  memcpy(iter, &child, sizeof(GtkTreeIter));
    475  break;
    476  }
    477  }
    478  ret = gtk_tree_model_iter_next(tree, iter);
    479  }
    480  return match;
    481 }
    482 
    483 static void remmina_main_load_file_tree_callback(RemminaFile *remminafile, gpointer user_data)
    484 {
    485  TRACE_CALL(__func__);
    486  GtkTreeIter iter, child;
    487  GtkTreeStore *store;
    488  gboolean found;
    489  gchar *datetime = NULL;
    490 
    491  store = GTK_TREE_STORE(user_data);
    492 
    493  found = FALSE;
    494  if (gtk_tree_model_get_iter_first(GTK_TREE_MODEL(store), &iter))
    495  found = remmina_main_load_file_tree_find(GTK_TREE_MODEL(store), &iter,
    496  remmina_file_get_string(remminafile, "group"));
    497 
    498  datetime = remmina_file_get_datetime(remminafile);
    499  //REMMINA_DEBUG("The date is %s", datetime);
    500  gtk_tree_store_append(store, &child, (found ? &iter : NULL));
    501  gtk_tree_store_set(store, &child,
    503  NAME_COLUMN, remmina_file_get_string(remminafile, "name"),
    504  NOTES_COLUMN, g_uri_unescape_string(remmina_file_get_string(remminafile, "notes_text"), NULL),
    505  GROUP_COLUMN, remmina_file_get_string(remminafile, "group"),
    506  SERVER_COLUMN, remmina_file_get_string(remminafile, "server"),
    507  PLUGIN_COLUMN, remmina_file_get_string(remminafile, "protocol"),
    508  DATE_COLUMN, datetime,
    510  LABELS_COLUMN, remmina_file_get_string(remminafile, "labels"),
    511  -1);
    512  g_free(datetime);
    513 }
    514 
    515 static void remmina_main_file_model_on_sort(GtkTreeSortable *sortable, gpointer user_data)
    516 {
    517  TRACE_CALL(__func__);
    518  gint columnid;
    519  GtkSortType order;
    520 
    521  gtk_tree_sortable_get_sort_column_id(sortable, &columnid, &order);
    525 }
    526 
    527 static gboolean remmina_main_filter_visible_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
    528 {
    529  TRACE_CALL(__func__);
    530  gchar *text;
    531  gchar *protocol, *name, *labels, *group, *server, *plugin, *date, *s;
    532  gboolean result = TRUE;
    533 
    534  text = g_ascii_strdown(gtk_entry_get_text(remminamain->entry_quick_connect_server), -1);
    535  if (text && text[0]) {
    536  gtk_tree_model_get(model, iter,
    537  PROTOCOL_COLUMN, &protocol,
    538  NAME_COLUMN, &name,
    539  GROUP_COLUMN, &group,
    540  SERVER_COLUMN, &server,
    541  PLUGIN_COLUMN, &plugin,
    542  DATE_COLUMN, &date,
    543  LABELS_COLUMN, &labels,
    544  -1);
    545  if (g_strcmp0(protocol, "folder-symbolic") != 0) {
    546  s = g_ascii_strdown(name ? name : "", -1);
    547  g_free(name);
    548  name = s;
    549  s = g_ascii_strdown(group ? group : "", -1);
    550  g_free(group);
    551  group = s;
    552  s = g_ascii_strdown(server ? server : "", -1);
    553  g_free(server);
    554  server = s;
    555  s = g_ascii_strdown(plugin ? plugin : "", -1);
    556  g_free(plugin);
    557  plugin = s;
    558  s = g_ascii_strdown(date ? date : "", -1);
    559  g_free(date);
    560  date = s;
    561  result = (strstr(name, text) || strstr(group, text) || strstr(server, text) || strstr(plugin, text) || strstr(date, text));
    562 
    563  // Filter by labels
    564 
    565  s = g_ascii_strdown(labels ? labels : "", -1);
    566  g_free(labels);
    567  labels = s;
    568 
    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);
    573 
    574  for (int t = 0; (NULL != text_array[t]); t++) {
    575  if (0 == strlen(text_array[t])) {
    576  continue;
    577  }
    578 
    579  gboolean text_result = FALSE;
    580 
    581  for (int l = 0; (NULL != labels_array[l]); l++) {
    582  if (0 == strlen(labels_array[l])) {
    583  continue;
    584  }
    585 
    586  text_result = (text_result || strstr(labels_array[l], text_array[t]));
    587 
    588  if (text_result) {
    589  break;
    590  }
    591  }
    592 
    593  labels_result = (labels_result && text_result);
    594 
    595  if (!labels_result) {
    596  break;
    597  }
    598  }
    599 
    600  result = (result || labels_result);
    601 
    602  g_strfreev(labels_array);
    603  g_strfreev(text_array);
    604  }
    605  }
    606  g_free(protocol);
    607  g_free(name);
    608  g_free(labels);
    609  g_free(group);
    610  g_free(server);
    611  g_free(plugin);
    612  g_free(date);
    613  }
    614  g_free(text);
    615  return result;
    616 }
    617 
    618 static void remmina_main_select_file(const gchar *filename)
    619 {
    620  TRACE_CALL(__func__);
    621  GtkTreeIter iter;
    622  GtkTreePath *path;
    623  gchar *item_filename;
    624  gboolean cmp;
    625 
    626  if (!gtk_tree_model_get_iter_first(remminamain->priv->file_model_sort, &iter))
    627  return;
    628 
    629  while (TRUE) {
    630  gtk_tree_model_get(remminamain->priv->file_model_sort, &iter, FILENAME_COLUMN, &item_filename, -1);
    631  cmp = g_strcmp0(item_filename, filename);
    632  g_free(item_filename);
    633  if (cmp == 0) {
    634  gtk_tree_selection_select_iter(gtk_tree_view_get_selection(remminamain->tree_files_list),
    635  &iter);
    636  path = gtk_tree_model_get_path(remminamain->priv->file_model_sort, &iter);
    637  gtk_tree_view_scroll_to_cell(remminamain->tree_files_list, path, NULL, TRUE, 0.5, 0.0);
    638  gtk_tree_path_free(path);
    639  return;
    640  }
    641  if (!gtk_tree_model_iter_next(remminamain->priv->file_model_sort, &iter))
    642  return;
    643  }
    644 }
    645 
    647 {
    648  TRACE_CALL(__func__);
    649  gint items_count;
    650  gchar buf[200];
    651  guint context_id;
    652  gint view_file_mode;
    653  gboolean always_show_notes;
    654  char *save_selected_filename;
    655  GtkTreeModel *newmodel;
    656  const gchar *neticon;
    657  const gchar *connection_tooltip;
    658 
    659  save_selected_filename = g_strdup(remminamain->priv->selected_filename);
    661 
    662  view_file_mode = remmina_pref.view_file_mode;
    663  if (remminamain->priv->override_view_file_mode_to_list)
    664  view_file_mode = REMMINA_VIEW_FILE_LIST;
    665 
    666  switch (remmina_pref.view_file_mode) {
    668  gtk_toggle_button_set_active(remminamain->view_toggle_button, FALSE);
    669  break;
    671  default:
    672  gtk_toggle_button_set_active(remminamain->view_toggle_button, TRUE);
    673  break;
    674  }
    675 
    676  switch (view_file_mode) {
    678  /* Create new GtkTreeStore model */
    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));
    680  /* Hide the Group column in the tree view mode */
    681  gtk_tree_view_column_set_visible(remminamain->column_files_list_group, FALSE);
    682  /* Load groups first */
    683  remmina_main_load_file_tree_group(GTK_TREE_STORE(newmodel));
    684  /* Load files list */
    685  items_count = remmina_file_manager_iterate((GFunc)remmina_main_load_file_tree_callback, (gpointer)newmodel);
    686  break;
    687 
    689  default:
    690  /* Create new GtkListStore model */
    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));
    692  /* Show the Group column in the list view mode */
    693  gtk_tree_view_column_set_visible(remminamain->column_files_list_group, TRUE);
    694  /* Load files list */
    695  items_count = remmina_file_manager_iterate((GFunc)remmina_main_load_file_list_callback, (gpointer)newmodel);
    696  break;
    697  }
    698 
    699  /* Set note column visibility*/
    700  always_show_notes = remmina_pref.always_show_notes;
    701  if (!always_show_notes){
    702  gtk_tree_view_column_set_visible(remminamain->column_files_list_notes, FALSE);
    703  }
    704 
    705  /* Unset old model */
    706  gtk_tree_view_set_model(remminamain->tree_files_list, NULL);
    707 
    708  /* Destroy the old model and save the new one */
    709  remminamain->priv->file_model = newmodel;
    710 
    711  /* Create a sorted filtered model based on newmodel and apply it to the TreeView */
    712  remminamain->priv->file_model_filter = gtk_tree_model_filter_new(remminamain->priv->file_model, NULL);
    713  gtk_tree_model_filter_set_visible_func(GTK_TREE_MODEL_FILTER(remminamain->priv->file_model_filter),
    714  (GtkTreeModelFilterVisibleFunc)remmina_main_filter_visible_func, NULL, NULL);
    715  remminamain->priv->file_model_sort = gtk_tree_model_sort_new_with_model(remminamain->priv->file_model_filter);
    716  gtk_tree_sortable_set_sort_column_id(GTK_TREE_SORTABLE(remminamain->priv->file_model_sort),
    719  gtk_tree_view_set_model(remminamain->tree_files_list, remminamain->priv->file_model_sort);
    720  g_signal_connect(G_OBJECT(remminamain->priv->file_model_sort), "sort-column-changed",
    721  G_CALLBACK(remmina_main_file_model_on_sort), NULL);
    723  /* Select the file previously selected */
    724  if (save_selected_filename) {
    725  remmina_main_select_file(save_selected_filename);
    726  g_free(save_selected_filename);
    727  }
    728  gtk_tree_view_column_set_widget(remminamain->column_files_list_date, NULL);
    729 
    730  GtkWidget *label = gtk_tree_view_column_get_button(remminamain->column_files_list_date);
    731 
    732  gtk_widget_set_tooltip_text(GTK_WIDGET(label),
    733  _("The latest successful connection attempt, or a pre-computed date"));
    734  /* Show in the status bar the total number of connections found */
    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");
    737  gtk_statusbar_pop(remminamain->statusbar_main, context_id);
    738  gtk_statusbar_push(remminamain->statusbar_main, context_id, buf);
    739 
    741  if (remminamain->monitor->connected){
    742  neticon = g_strdup("network-transmit-receive-symbolic");
    743  connection_tooltip = g_strdup(_("Network status: fully online"));
    744  } else {
    745  neticon = g_strdup("network-offline-symbolic");
    746  connection_tooltip = g_strdup(_("Network status: offline"));
    747  }
    748 
    749  if (GTK_IS_WIDGET(remminamain->network_icon))
    750  gtk_widget_destroy(remminamain->network_icon);
    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);
    754 
    755  g_object_unref (icon);
    756 
    757  gtk_box_pack_start (GTK_BOX(remminamain->statusbar_main), remminamain->network_icon, FALSE, FALSE, 0);
    758  gtk_widget_show (remminamain->network_icon);
    759 
    760 }
    761 
    762 void remmina_main_load_files_cb(GtkEntry *entry, char *string, gpointer user_data)
    763 {
    764  TRACE_CALL(__func__);
    766 }
    767 
    768 void remmina_main_on_action_connection_connect(GSimpleAction *action, GVariant *param, gpointer data)
    769 {
    770  TRACE_CALL(__func__);
    771 
    772  RemminaFile *remminafile;
    773 
    774  if (!remminamain->priv->selected_filename)
    775  return;
    776 
    777  remminafile = remmina_file_load(remminamain->priv->selected_filename);
    778 
    779  if (remminafile == NULL)
    780  return;
    781 
    782  if (remmina_pref_get_boolean("use_primary_password")
    783  && remmina_pref_get_boolean("lock_connect")
    784  && remmina_unlock_new(remminamain->window) == 0)
    785  return;
    786  if (remmina_file_get_int (remminafile, "profile-lock", FALSE) == 1
    787  && remmina_unlock_new(remminamain->window) == 0)
    788  return;
    789 
    790  remmina_file_touch(remminafile);
    792 
    793  remmina_file_free(remminafile);
    794 }
    795 
    796 void remmina_main_on_action_connection_external_tools(GSimpleAction *action, GVariant *param, gpointer data)
    797 {
    798  TRACE_CALL(__func__);
    799  if (!remminamain->priv->selected_filename)
    800  return;
    801 
    802  remmina_external_tools_from_filename(remminamain, remminamain->priv->selected_filename);
    803 }
    804 
    805 static void remmina_main_file_editor_destroy(GtkWidget *widget, gpointer user_data)
    806 {
    807  TRACE_CALL(__func__);
    808 
    809  if (!remminamain)
    810  return;
    812 }
    813 
    814 void remmina_main_on_action_application_mpchange(GSimpleAction *action, GVariant *param, gpointer data)
    815 {
    816  TRACE_CALL(__func__);
    817  RemminaFile *remminafile;
    818 
    819  const gchar *username;
    820  const gchar *domain;
    821  const gchar *group;
    822  const gchar *gatewayusername;
    823  const gchar *gatewaydomain;
    824 
    825  username = domain = group = gatewayusername = gatewaydomain = "";
    826 
    827  remminafile = NULL;
    828 
    829  if (remmina_pref_get_boolean("use_primary_password")
    830  && remmina_pref_get_boolean("lock_edit")
    831  && remmina_unlock_new(remminamain->window) == 0)
    832  return;
    833 
    834  if (remminamain->priv->selected_filename) {
    835  remminafile = remmina_file_load(remminamain->priv->selected_filename);
    836  if (remminafile != NULL) {
    837  username = remmina_file_get_string(remminafile, "username");
    838  domain = remmina_file_get_string(remminafile, "domain");
    839  group = remmina_file_get_string(remminafile, "group");
    840  gatewayusername = remmina_file_get_string(remminafile, "gateway_username");
    841  gatewaydomain = remmina_file_get_string(remminafile, "gateway_domain");
    842  }
    843  }
    844 
    845  remmina_mpchange_schedule(TRUE, group, domain, username, "", gatewayusername, gatewaydomain, "");
    846 
    847  if (remminafile != NULL)
    848  remmina_file_free(remminafile);
    849 }
    850 
    851 void remmina_main_on_action_connection_new(GSimpleAction *action, GVariant *param, gpointer data)
    852 {
    853  TRACE_CALL(__func__);
    854  if (kioskmode && kioskmode == TRUE)
    855  return;
    856  GtkWidget *widget;
    857 
    858  if (remmina_pref_get_boolean("use_primary_password")
    859  && remmina_pref_get_boolean("lock_edit")
    860  && remmina_unlock_new(remminamain->window) == 0)
    861  return;
    862 
    863  widget = remmina_file_editor_new();
    864  g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(remmina_main_file_editor_destroy), remminamain);
    865  gtk_window_set_transient_for(GTK_WINDOW(widget), remminamain->window);
    866  gtk_widget_show(widget);
    868 }
    869 
    870 static gboolean remmina_main_search_key_event(GtkWidget *search_entry, GdkEventKey *event, gpointer user_data)
    871 {
    872  TRACE_CALL(__func__);
    873  if (event->keyval == GDK_KEY_Escape) {
    874  gtk_entry_set_text(remminamain->entry_quick_connect_server, "");
    875  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(RM_GET_OBJECT("search_toggle")), FALSE);
    876  return TRUE;
    877  }
    878  return FALSE;
    879 }
    880 
    881 static gboolean remmina_main_tree_row_activated(GtkTreeView *tree, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data)
    882 {
    883  TRACE_CALL(__func__);
    884  if (gtk_tree_view_row_expanded(tree, path))
    885  gtk_tree_view_collapse_row(tree, path);
    886  else
    887  gtk_tree_view_expand_row(tree, path, FALSE);
    888  return TRUE;
    889 }
    890 
    892 {
    893  if (gtk_toggle_button_get_active(remminamain->view_toggle_button)) {
    896  gtk_entry_set_text(remminamain->entry_quick_connect_server, "");
    899  }
    900  } else {
    903  gtk_entry_set_text(remminamain->entry_quick_connect_server, "");
    906  }
    907  }
    908 }
    909 
    910 void remmina_main_on_action_connection_copy(GSimpleAction *action, GVariant *param, gpointer data)
    911 {
    912  TRACE_CALL(__func__);
    913  GtkWidget *widget;
    914 
    915  if (remmina_pref_get_boolean("use_primary_password")
    916  && remmina_unlock_new(remminamain->window) == 0)
    917  return;
    918 
    919  if (!remminamain->priv->selected_filename)
    920  return;
    921 
    922  RemminaFile *remminafile = remmina_file_load(remminamain->priv->selected_filename);
    923 
    924  if (((remmina_pref_get_boolean("lock_edit")
    925  && remmina_pref_get_boolean("use_primary_password"))
    926  || remmina_file_get_int (remminafile, "profile-lock", FALSE))
    927  && remmina_unlock_new(remminamain->window) == 0)
    928  return;
    929 
    930  if (remminafile) {
    931  remmina_file_free(remminafile);
    932  remminafile = NULL;
    933  }
    934 
    935  widget = remmina_file_editor_new_copy(remminamain->priv->selected_filename);
    936  if (widget) {
    937  g_signal_connect(G_OBJECT(widget), "destroy", G_CALLBACK(remmina_main_file_editor_destroy), remminamain);
    938  gtk_window_set_transient_for(GTK_WINDOW(widget), remminamain->window);
    939  gtk_widget_show(widget);
    940  }
    941  /* Select the file previously selected */
    942  if (remminamain->priv->selected_filename)
    944 }
    945 
    946 void remmina_main_on_action_connection_edit(GSimpleAction *action, GVariant *param, gpointer data)
    947 {
    948  TRACE_CALL(__func__);
    949  GtkWidget *widget;
    950 
    951  if (!remminamain->priv->selected_filename)
    952  return;
    953 
    954  RemminaFile *remminafile = remmina_file_load(remminamain->priv->selected_filename);
    955 
    956  if (remmina_pref_get_boolean("use_primary_password")
    957  && (remmina_pref_get_boolean("lock_edit")
    958  || remmina_file_get_int (remminafile, "profile-lock", FALSE))
    959  && remmina_unlock_new(remminamain->window) == 0)
    960  return;
    961 
    962  if (remminafile) {
    963  remmina_file_free(remminafile);
    964  remminafile = NULL;
    965  }
    966 
    968  if (widget) {
    969  gtk_window_set_transient_for(GTK_WINDOW(widget), remminamain->window);
    970  gtk_widget_show(widget);
    971  }
    972 /* Select the file previously selected */
    973  if (remminamain->priv->selected_filename)
    975 }
    976 
    977 void remmina_main_on_action_connection_delete(GSimpleAction *action, GVariant *param, gpointer data)
    978 {
    979  TRACE_CALL(__func__);
    980  GtkWidget *dialog;
    981 
    982  if (!remminamain->priv->selected_filename)
    983  return;
    984 
    985  RemminaFile *remminafile = remmina_file_load(remminamain->priv->selected_filename);
    986 
    987  if (((remmina_pref_get_boolean("lock_edit")
    988  && remmina_pref_get_boolean("use_primary_password"))
    989  || remmina_file_get_int (remminafile, "profile-lock", FALSE))
    990  && remmina_unlock_new(remminamain->window) == 0)
    991  return;
    992 
    993  if (remminafile) {
    994  remmina_file_free(remminafile);
    995  remminafile = NULL;
    996  }
    997 
    998  dialog = gtk_message_dialog_new(remminamain->window, GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO,
    999  _("Are you sure you want to delete “%s”?"), remminamain->priv->selected_name);
    1000  if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_YES) {
    1001  gchar *delfilename = g_strdup(remminamain->priv->selected_filename);
    1002  remmina_file_delete(delfilename);
    1003  g_free(delfilename), delfilename = NULL;
    1006  }
    1007  gtk_widget_destroy(dialog);
    1009 }
    1010 
    1011 void remmina_main_on_action_connection_delete_multiple(GSimpleAction *action, GVariant *param, gpointer data)
    1012 {
    1013  TRACE_CALL(__func__);
    1014  GtkWidget *dialog;
    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;
    1019 
    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?"));
    1022 
    1023  // Delete files if Yes is clicked
    1024  if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_YES) {
    1025  while (list) {
    1026  GtkTreePath *path = list->data;
    1027  GtkTreeIter iter;
    1028 
    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);
    1037  return;
    1038  }
    1039 
    1040  gtk_tree_model_get(model, &iter,
    1041  FILENAME_COLUMN, &file_to_delete, -1);
    1042 
    1043  RemminaFile *remminafile = remmina_file_load(file_to_delete);
    1044 
    1045  if (((remmina_pref_get_boolean("lock_edit")
    1046  && remmina_pref_get_boolean("use_primary_password"))
    1047  || remmina_file_get_int (remminafile, "profile-lock", FALSE))
    1048  && remmina_unlock_new(remminamain->window) == 0)
    1049  return;
    1050 
    1051  if (remminafile) {
    1052  remmina_file_free(remminafile);
    1053  remminafile = NULL;
    1054  }
    1055 
    1056  gchar *delfilename = g_strdup(file_to_delete);
    1057  remmina_file_delete(delfilename);
    1058  g_free(delfilename), delfilename = NULL;
    1061  list = g_list_next(list);
    1062  }
    1063  }
    1064 
    1065  gtk_widget_destroy(dialog);
    1067 }
    1068 
    1069 void remmina_main_on_accel_application_preferences(GSimpleAction *action, GVariant *param, gpointer data)
    1070 {
    1071  TRACE_CALL(__func__);
    1072  GVariant *v = g_variant_new("i", 0);
    1073 
    1075 }
    1076 
    1078 {
    1079  GtkSettings *settings;
    1080  settings = gtk_settings_get_default();
    1081  g_object_set(settings, "gtk-application-prefer-dark-theme", remmina_pref.dark_theme, NULL);
    1083  gtk_toggle_button_set_active(remminamain->search_toggle, FALSE);
    1084  }
    1085  else{
    1086  gtk_toggle_button_set_active(remminamain->search_toggle, TRUE);
    1087  }
    1088  gtk_tree_view_column_set_visible(remminamain->column_files_list_notes, remmina_pref.always_show_notes);
    1089 }
    1090 
    1091 void remmina_main_on_action_application_preferences(GSimpleAction *action, GVariant *param, gpointer data)
    1092 {
    1093  TRACE_CALL(__func__);
    1094 
    1095  REMMINA_DEBUG("Opening the preferences");
    1096  gint32 tab_num;
    1097 
    1098  if (param) {
    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);
    1102  } else {
    1103  tab_num = 0;
    1104  }
    1105 
    1106  if (remmina_pref_get_boolean("use_primary_password")
    1107  && remmina_unlock_new(remminamain->window) == 0)
    1108  return;
    1109 
    1110  GtkWidget *widget = remmina_pref_dialog_new(tab_num, remminamain->window);
    1111 
    1112  gtk_widget_show_all(widget);
    1113 }
    1114 
    1115 void remmina_main_on_action_application_default(GSimpleAction *action, GVariant *param, gpointer data)
    1116 {
    1117  TRACE_CALL(__func__);
    1118 #ifndef __APPLE__
    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);
    1123  int i;
    1124 
    1125  desktop_info = g_desktop_app_info_new(id);
    1126  if (!desktop_info)
    1127  return;
    1128 
    1129  info = G_APP_INFO(desktop_info);
    1130 
    1131  for (i = 0; supported_mime_types[i]; i++) {
    1132  if (!g_app_info_set_as_default_for_type(info, supported_mime_types[i], &error))
    1133  g_warning("Failed to set '%s' as the default application for secondary content type '%s': %s",
    1134  g_app_info_get_name(info), supported_mime_types[i], error->message);
    1135  else
    1136  g_debug("Set '%s' as the default application for '%s'",
    1137  g_app_info_get_name(info),
    1139  }
    1140 #endif
    1141 }
    1142 
    1143 void remmina_main_on_action_application_quit(GSimpleAction *action, GVariant *param, gpointer data)
    1144 {
    1145  // Called by quit signal in remmina_main.glade
    1146  TRACE_CALL(__func__);
    1147  g_debug("Quit intercept");
    1149 }
    1150 
    1152 {
    1155  gtk_entry_set_text(remminamain->entry_quick_connect_server, "");
    1158  }
    1159 }
    1160 
    1161 void remmina_main_toggle_password_view(GtkWidget *widget, gpointer data)
    1162 {
    1163  GtkWindow *mainwindow;
    1164  gboolean visible = gtk_entry_get_visibility(GTK_ENTRY(widget));
    1165 
    1166  mainwindow = remmina_main_get_window();
    1167  if (remmina_pref_get_boolean("use_primary_password") && remmina_pref_get_boolean("lock_view_passwords") && remmina_unlock_new(mainwindow) == 0)
    1168  return;
    1169 
    1170  if (visible) {
    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");
    1173  } else {
    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");
    1176  }
    1177 }
    1178 
    1179 static void remmina_main_import_file_list(GSList *files)
    1180 {
    1181  TRACE_CALL(__func__);
    1182  GtkWidget *dlg;
    1183  GSList *element;
    1184  gchar *path;
    1185  RemminaFilePlugin *plugin;
    1186  GString *err;
    1187  RemminaFile *remminafile = NULL;
    1188  gboolean imported;
    1189 
    1190  err = g_string_new(NULL);
    1191  imported = FALSE;
    1192  for (element = files; element; element = element->next) {
    1193  path = (gchar *)element->data;
    1195  if (plugin && (remminafile = plugin->import_func(plugin, path)) != NULL && remmina_file_get_string(remminafile, "name")) {
    1196  remmina_file_generate_filename(remminafile);
    1197  remmina_file_save(remminafile);
    1198  imported = TRUE;
    1199  } else {
    1200  g_string_append(err, path);
    1201  g_string_append_c(err, '\n');
    1202  }
    1203  if (remminafile) {
    1204  remmina_file_free(remminafile);
    1205  remminafile = NULL;
    1206  }
    1207  g_free(path);
    1208  }
    1209  g_slist_free(files);
    1210  if (err->len > 0) {
    1211  // TRANSLATORS: The placeholder %s is an error message
    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);
    1216  }
    1217  g_string_free(err, TRUE);
    1218  if (imported)
    1220 }
    1221 
    1222 static void remmina_main_action_tools_import_on_response(GtkDialog *dialog, gint response_id, gpointer user_data)
    1223 {
    1224  TRACE_CALL(__func__);
    1225  GSList *files;
    1226 
    1227  if (response_id == GTK_RESPONSE_ACCEPT) {
    1228  files = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
    1230  }
    1231  gtk_widget_destroy(GTK_WIDGET(dialog));
    1232 }
    1233 
    1234 void remmina_main_on_action_tools_import(GSimpleAction *action, GVariant *param, gpointer data)
    1235 {
    1236  TRACE_CALL(__func__);
    1237  GtkWidget *dialog;
    1238 
    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);
    1242  g_signal_connect(G_OBJECT(dialog), "response", G_CALLBACK(remmina_main_action_tools_import_on_response), NULL);
    1243  gtk_widget_show(dialog);
    1244 }
    1245 
    1246 void remmina_main_on_action_tools_export(GSimpleAction *action, GVariant *param, gpointer data)
    1247 {
    1248  TRACE_CALL(__func__);
    1249  RemminaFilePlugin *plugin;
    1250  RemminaFile *remminafile;
    1251  GtkWidget *dialog;
    1252 
    1253  if (!remminamain->priv->selected_filename)
    1254  return;
    1255 
    1256  remminafile = remmina_file_load(remminamain->priv->selected_filename);
    1257  if (remminafile == NULL)
    1258  return;
    1259  plugin = remmina_plugin_manager_get_export_file_handler(remminafile);
    1260  if (plugin) {
    1261  dialog = gtk_file_chooser_dialog_new(plugin->export_hints, remminamain->window,
    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);
    1266  } else {
    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);
    1271  }
    1272  remmina_file_free(remminafile);
    1273 }
    1274 
    1275 void remmina_main_on_action_application_plugins(GSimpleAction *action, GVariant *param, gpointer data)
    1276 {
    1277  TRACE_CALL(__func__);
    1278  remmina_plugin_manager_show(remminamain->window);
    1279 }
    1280 
    1281 void remmina_main_on_action_application_dark_theme(GSimpleAction *action, GVariant *param, gpointer data)
    1282 {
    1283  TRACE_CALL(__func__);
    1284  GtkSettings *settings;
    1285 
    1286  settings = gtk_settings_get_default();
    1287 
    1288  if (gtk_switch_get_active(remminamain->switch_dark_mode))
    1290  else
    1293 
    1294  g_object_set(settings, "gtk-application-prefer-dark-theme", remmina_pref.dark_theme, NULL);
    1295 }
    1296 
    1297 void remmina_main_on_action_help_homepage(GSimpleAction *action, GVariant *param, gpointer data)
    1298 {
    1299  TRACE_CALL(__func__);
    1300  g_app_info_launch_default_for_uri("https://www.remmina.org", NULL, NULL);
    1301 }
    1302 
    1303 void remmina_main_on_action_help_wiki(GSimpleAction *action, GVariant *param, gpointer data)
    1304 {
    1305  TRACE_CALL(__func__);
    1306  g_app_info_launch_default_for_uri("https://gitlab.com/Remmina/Remmina/wikis/home", NULL, NULL);
    1307 }
    1308 
    1309 void remmina_main_on_action_help_community(GSimpleAction *action, GVariant *param, gpointer data)
    1310 {
    1311  TRACE_CALL(__func__);
    1312  g_app_info_launch_default_for_uri("https://remmina.org/community", NULL, NULL);
    1313 }
    1314 
    1315 void remmina_main_on_action_help_donations(GSimpleAction *action, GVariant *param, gpointer data)
    1316 {
    1317  TRACE_CALL(__func__);
    1318  g_app_info_launch_default_for_uri("https://www.remmina.org/donations", NULL, NULL);
    1319 }
    1320 
    1321 void remmina_main_on_action_help_debug(GSimpleAction *action, GVariant *param, gpointer data)
    1322 {
    1323  TRACE_CALL(__func__);
    1325 }
    1326 
    1327 void remmina_main_on_action_application_about(GSimpleAction *action, GVariant *param, gpointer data)
    1328 {
    1329  TRACE_CALL(__func__);
    1330  remmina_about_open(remminamain->window);
    1331 };
    1332 
    1333 static gboolean is_empty(const gchar *s)
    1334 {
    1335  if (s == NULL)
    1336  return TRUE;
    1337  while (*s != 0) {
    1338  if (!isspace((unsigned char)*s))
    1339  return FALSE;
    1340  s++;
    1341  }
    1342  return TRUE;
    1343 }
    1344 
    1345 static gboolean remmina_main_quickconnect(void)
    1346 {
    1347  TRACE_CALL(__func__);
    1348  RemminaFile *remminafile;
    1349  gchar *server;
    1350  gchar *server_trimmed;
    1351  gchar *qcp;
    1352 
    1353 
    1354  /* Save quick connect protocol if different from the previous one */
    1355  qcp = gtk_combo_box_text_get_active_text(remminamain->combo_quick_connect_protocol);
    1356  if (qcp && strcmp(qcp, remmina_pref.last_quickconnect_protocol) != 0) {
    1358  remmina_pref.last_quickconnect_protocol = g_strdup(qcp);
    1360  }
    1361 
    1362  remminafile = remmina_file_new();
    1363  server = g_strdup(gtk_entry_get_text(remminamain->entry_quick_connect_server));
    1364  if (g_hostname_to_ascii(server) == NULL)
    1365  return FALSE;
    1366  /* If server contain /, e.g. vnc://, it won't connect
    1367  * We could search for an array of invalid characters, but
    1368  * it's better to find a way to correctly parse and validate addresses
    1369  */
    1370  if (g_strrstr(server, "/") != NULL)
    1371  return FALSE;
    1372  //if (g_str_has_suffix (server, "/"))
    1373  //return FALSE;
    1374  if (is_empty(server))
    1375  return FALSE;
    1376 
    1377  /* check if server is an IP address and trim whitespace if so */
    1378  server_trimmed = g_strdup(server);
    1379  g_strstrip(server_trimmed);
    1380  gchar **strings = g_strsplit(server_trimmed, ":", 2);
    1381 
    1382  if (strings[0] != NULL)
    1383  if (g_hostname_is_ip_address(strings[0]))
    1384  g_stpcpy(server, server_trimmed);
    1385 
    1386  remmina_file_set_string(remminafile, "sound", "off");
    1387  remmina_file_set_string(remminafile, "server", server);
    1388  remmina_file_set_string(remminafile, "name", server);
    1389  remmina_file_set_string(remminafile, "protocol", qcp);
    1390  g_free(server);
    1391  g_free(server_trimmed);
    1392  g_free(qcp);
    1393 
    1394  rcw_open_from_file(remminafile);
    1395 
    1396  return FALSE;
    1397 }
    1398 
    1399 gboolean remmina_main_quickconnect_on_click(GtkWidget *widget, gpointer user_data)
    1400 {
    1401  TRACE_CALL(__func__);
    1402  if (!kioskmode && kioskmode == FALSE)
    1403  return remmina_main_quickconnect();
    1404  return FALSE;
    1405 }
    1406 
    1407 /* Select all the text inside the quick search box if there is anything */
    1408 void remmina_main_quick_search_enter(GtkWidget *widget, gpointer user_data)
    1409 {
    1410  if (gtk_entry_get_text(remminamain->entry_quick_connect_server))
    1411  gtk_editable_select_region(GTK_EDITABLE(remminamain->entry_quick_connect_server), 0, -1);
    1412 }
    1413 
    1414 void remmina_main_on_action_collapse(GSimpleAction *action, GVariant *param, gpointer data)
    1415 {
    1416  TRACE_CALL(__func__);
    1417  gtk_tree_view_collapse_all(remminamain->tree_files_list);
    1418 }
    1419 
    1420 void remmina_main_on_action_search_toggle(GSimpleAction *action, GVariant *param, gpointer data)
    1421 {
    1422  TRACE_CALL(__func__);
    1423  REMMINA_DEBUG("Search toggle triggered");
    1424 
    1425  gboolean toggle_status = gtk_toggle_button_get_active(remminamain->search_toggle);
    1426 
    1427  gtk_search_bar_set_search_mode(remminamain->search_bar, toggle_status);
    1428  if (toggle_status) {
    1429  REMMINA_DEBUG("Search toggle is active");
    1430  gtk_widget_grab_focus(GTK_WIDGET(remminamain->entry_quick_connect_server));
    1431  } else {
    1432  REMMINA_DEBUG("Search toggle is not active, focus is tree_files_list");
    1433  gtk_widget_grab_focus(GTK_WIDGET(remminamain->tree_files_list));
    1434  }
    1435 }
    1436 
    1438 {
    1439  TRACE_CALL(__func__);
    1440  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(remminamain->search_toggle), TRUE);
    1441 }
    1442 
    1443 void remmina_main_on_action_expand(GSimpleAction *action, GVariant *param, gpointer data)
    1444 {
    1445  TRACE_CALL(__func__);
    1446  gtk_tree_view_expand_all(remminamain->tree_files_list);
    1447 }
    1448 
    1449 /* Handle double click on a row in the connections list */
    1450 void remmina_main_file_list_on_row_activated(GtkTreeView *tree, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data)
    1451 {
    1452  TRACE_CALL(__func__);
    1453 /* If a connection was selected then execute the default action */
    1454  if (remminamain->priv->selected_filename) {
    1455  switch (remmina_pref.default_action) {
    1456  case REMMINA_ACTION_EDIT:
    1457  remmina_main_on_action_connection_edit(NULL, NULL, NULL);
    1458  break;
    1460  default:
    1462  break;
    1463  }
    1464  }
    1465 }
    1466 
    1467 /* Show the popup menu by the right button mouse click */
    1468 gboolean remmina_main_file_list_on_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
    1469 {
    1470  TRACE_CALL(__func__);
    1471  if (event->button == MOUSE_BUTTON_RIGHT) {
    1472  if (!kioskmode && kioskmode == FALSE) {
    1473 #if GTK_CHECK_VERSION(3, 22, 0)
    1474  // For now, if more than one selected row, display only a delete menu option
    1475  if (gtk_tree_selection_count_selected_rows(gtk_tree_view_get_selection(remminamain->tree_files_list)) > 1) {
    1476  gtk_menu_popup_at_pointer(GTK_MENU(remminamain->menu_popup_delete_rc), (GdkEvent *)event);
    1477  return GDK_EVENT_STOP;
    1478  }
    1479  else {
    1480  gtk_menu_popup_at_pointer(GTK_MENU(remminamain->menu_popup), (GdkEvent *)event);
    1481  }
    1482 #else
    1483  gtk_menu_popup(remminamain->menu_popup, NULL, NULL, NULL, NULL, event->button, event->time);
    1484 #endif
    1485  }
    1486  }
    1487  return FALSE;
    1488 }
    1489 
    1490 /* Show the popup menu by the menu key */
    1491 gboolean remmina_main_file_list_on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
    1492 {
    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,
    1498  (GdkEvent *)event);
    1499 #else
    1500  gtk_menu_popup(remminamain->menu_popup, NULL, NULL, NULL, NULL, 0, event->time);
    1501 #endif
    1502  }
    1503  return FALSE;
    1504 }
    1505 
    1506 void remmina_main_quick_search_on_icon_press(GtkEntry *entry, GtkEntryIconPosition icon_pos, GdkEvent *event, gpointer user_data)
    1507 {
    1508  TRACE_CALL(__func__);
    1509  if (icon_pos == GTK_ENTRY_ICON_SECONDARY)
    1510  gtk_entry_set_text(entry, "");
    1511 }
    1512 
    1513 void remmina_main_quick_search_on_changed(GtkEditable *editable, gpointer user_data)
    1514 {
    1515  TRACE_CALL(__func__);
    1516  /* If a search text was input then temporary set the file mode to list */
    1517  if (gtk_entry_get_text_length(remminamain->entry_quick_connect_server)) {
    1518  if (GTK_IS_TREE_STORE(remminamain->priv->file_model)) {
    1519  /* File view mode changed, put it to override and reload list */
    1520  remminamain->priv->override_view_file_mode_to_list = TRUE;
    1522  }
    1523  } else {
    1524  if (remminamain->priv->override_view_file_mode_to_list) {
    1525  /* File view mode changed, put it to default (disable override) and reload list */
    1526  remminamain->priv->override_view_file_mode_to_list = FALSE;
    1528  }
    1529  }
    1530  gtk_tree_model_filter_refilter(GTK_TREE_MODEL_FILTER(remminamain->priv->file_model_filter));
    1531 }
    1532 
    1533 void remmina_main_on_drag_data_received(GtkWidget *widget, GdkDragContext *drag_context, gint x, gint y,
    1534  GtkSelectionData *data, guint info, guint time, gpointer user_data)
    1535 {
    1536  TRACE_CALL(__func__);
    1537  gchar **uris;
    1538  GSList *files = NULL;
    1539  gint i;
    1540 
    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)
    1544  continue;
    1545  files = g_slist_append(files, g_strdup(uris[i] + 7));
    1546  }
    1547  g_strfreev(uris);
    1549 }
    1550 
    1551 /* Add a new menuitem to the Tools menu */
    1552 static gboolean remmina_main_add_tool_plugin(gchar *name, RemminaPlugin *plugin, gpointer user_data)
    1553 {
    1554  TRACE_CALL(__func__);
    1555  RemminaToolPlugin *tool_plugin = (RemminaToolPlugin *)plugin;
    1556  GtkWidget *menuitem = gtk_menu_item_new_with_label(plugin->description);
    1557 
    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);
    1561  return FALSE;
    1562 }
    1563 
    1564 gboolean remmina_main_on_window_state_event(GtkWidget *widget, GdkEventWindowState *event, gpointer user_data)
    1565 {
    1566  TRACE_CALL(__func__);
    1567  return FALSE;
    1568 }
    1569 
    1570 /* Remmina main window initialization */
    1571 static void remmina_main_init(void)
    1572 {
    1573  TRACE_CALL(__func__);
    1574  int i, qcp_idx, qcp_actidx;
    1575  char *name;
    1576  GtkSettings *settings;
    1577 
    1578  REMMINA_DEBUG("Initializing the Remmina main window");
    1579  /* Switch to a dark theme if the user enabled it */
    1580  settings = gtk_settings_get_default();
    1581  g_object_set(settings, "gtk-application-prefer-dark-theme", remmina_pref.dark_theme, NULL);
    1582 
    1583  REMMINA_DEBUG ("Initializing monitor");
    1584  remminamain->monitor = remmina_network_monitor_new();
    1585 
    1587  if (!kioskmode && kioskmode == FALSE)
    1588  gtk_window_set_title(remminamain->window, _("Remmina Remote Desktop Client"));
    1589  else
    1590  gtk_window_set_title(remminamain->window, _("Remmina Kiosk"));
    1591  if (!kioskmode && kioskmode == FALSE) {
    1592  gtk_window_set_default_size(remminamain->window, remmina_pref.main_width, remmina_pref.main_height);
    1594  gtk_window_maximize(remminamain->window);
    1595  }
    1596  /* Honor global preferences Search Bar visibility */
    1598  gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(RM_GET_OBJECT("search_toggle")), FALSE);
    1599 
    1600  /* Add a GtkMenuItem to the Tools menu for each plugin of type REMMINA_PLUGIN_TYPE_TOOL */
    1602 
    1603  /* Add available quick connect protocols to remminamain->combo_quick_connect_protocol */
    1604  qcp_idx = qcp_actidx = 0;
    1605  for (i = 0; i < sizeof(quick_connect_plugin_list) / sizeof(quick_connect_plugin_list[0]); i++) {
    1606  name = quick_connect_plugin_list[i];
    1608  gtk_combo_box_text_append(remminamain->combo_quick_connect_protocol, name, name);
    1610  qcp_actidx = qcp_idx;
    1611  qcp_idx++;
    1612  }
    1613  }
    1614  gtk_combo_box_set_active(GTK_COMBO_BOX(remminamain->combo_quick_connect_protocol), qcp_actidx);
    1615 
    1616  /* Connect the group accelerators to the GtkWindow */
    1617  //gtk_window_add_accel_group(remminamain->window, remminamain->accelgroup_shortcuts);
    1618  /* Set the Quick Connection */
    1619  gtk_entry_set_activates_default(remminamain->entry_quick_connect_server, TRUE);
    1620  /* Set the TreeView for the files list */
    1621  gtk_tree_selection_set_select_function(
    1622  gtk_tree_view_get_selection(remminamain->tree_files_list),
    1623  remmina_main_selection_func, NULL, NULL);
    1625  gtk_tree_view_set_search_entry(remminamain->tree_files_list, GTK_ENTRY(remminamain->entry_quick_connect_server));
    1627  gtk_widget_grab_focus(GTK_WIDGET(remminamain->tree_files_list));
    1628  /* Load the files list */
    1630 
    1631  /* Drag-n-drop support */
    1632  gtk_drag_dest_set(GTK_WIDGET(remminamain->window), GTK_DEST_DEFAULT_ALL, remmina_drop_types, 1, GDK_ACTION_COPY);
    1633 
    1634  /* Finish initialization */
    1635  remminamain->priv->initialized = TRUE;
    1636 
    1637  /* Register the window in remmina_widget_pool with GType=GTK_WINDOW and TAG=remmina-main-window */
    1638  g_object_set_data(G_OBJECT(remminamain->window), "tag", "remmina-main-window");
    1639  remmina_widget_pool_register(GTK_WIDGET(remminamain->window));
    1640 }
    1641 
    1642 /* Signal handler for "show" on remminamain->window */
    1643 void remmina_main_on_show(GtkWidget *w, gpointer user_data)
    1644 {
    1645  TRACE_CALL(__func__);
    1646 #ifdef SNAP_BUILD
    1648 #endif
    1649 }
    1650 
    1651 /* RemminaMain instance */
    1652 GtkWidget *remmina_main_new(void)
    1653 {
    1654  TRACE_CALL(__func__);
    1655  GSimpleActionGroup *actions;
    1656  GtkAccelGroup *accel_group = NULL;
    1657 
    1658  remminamain = g_new0(RemminaMain, 1);
    1659  remminamain->priv = g_new0(RemminaMainPriv, 1);
    1660  /* Assign UI widgets to the private members */
    1661  remminamain->builder = remmina_public_gtk_builder_new_from_resource("/org/remmina/Remmina/src/../data/ui/remmina_main.glade");
    1662  remminamain->window = GTK_WINDOW(RM_GET_OBJECT("RemminaMain"));
    1663  if (kioskmode && kioskmode == TRUE) {
    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);
    1667  }
    1668  /* New Button */
    1669  remminamain->button_new = GTK_BUTTON(RM_GET_OBJECT("button_new"));
    1670  if (kioskmode && kioskmode == TRUE)
    1671  gtk_widget_set_sensitive(GTK_WIDGET(remminamain->button_new), FALSE);
    1672  /* Search bar */
    1673  remminamain->search_toggle = GTK_TOGGLE_BUTTON(RM_GET_OBJECT("search_toggle"));
    1674  remminamain->search_bar = GTK_SEARCH_BAR(RM_GET_OBJECT("search_bar"));
    1675  /* view mode list/tree */
    1676  remminamain->view_toggle_button = GTK_TOGGLE_BUTTON(RM_GET_OBJECT("view_toggle_button"));
    1677  if (kioskmode && kioskmode == TRUE)
    1678  gtk_widget_set_sensitive(GTK_WIDGET(remminamain->view_toggle_button), FALSE);
    1679 
    1680  /* Menu widgets */
    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"));
    1684  remminamain->menu_popup_delete_rc = GTK_MENU(RM_GET_OBJECT("menu_popup_delete_rc"));
    1685  if (kioskmode && kioskmode == TRUE) {
    1686  gtk_widget_set_sensitive(GTK_WIDGET(remminamain->menu_popup_full), FALSE);
    1687  gtk_widget_set_sensitive(GTK_WIDGET(remminamain->menu_header_button), FALSE);
    1688  }
    1689  /* View mode radios */
    1690  remminamain->menuitem_view_mode_list = GTK_RADIO_MENU_ITEM(RM_GET_OBJECT("menuitem_view_mode_list"));
    1691  remminamain->menuitem_view_mode_tree = GTK_RADIO_MENU_ITEM(RM_GET_OBJECT("menuitem_view_mode_tree"));
    1692  /* Quick connect objects */
    1693  remminamain->box_quick_connect = GTK_BOX(RM_GET_OBJECT("box_quick_connect"));
    1694  remminamain->combo_quick_connect_protocol = GTK_COMBO_BOX_TEXT(RM_GET_OBJECT("combo_quick_connect_protocol"));
    1695  if (kioskmode && kioskmode == TRUE)
    1696  gtk_widget_set_sensitive(GTK_WIDGET(remminamain->combo_quick_connect_protocol), FALSE);
    1697  remminamain->entry_quick_connect_server = GTK_ENTRY(RM_GET_OBJECT("entry_quick_connect_server"));
    1698  /* Other widgets */
    1699  remminamain->tree_files_list = GTK_TREE_VIEW(RM_GET_OBJECT("tree_files_list"));
    1700  remminamain->column_files_list_name = GTK_TREE_VIEW_COLUMN(RM_GET_OBJECT("column_files_list_name"));
    1701  remminamain->column_files_list_group = GTK_TREE_VIEW_COLUMN(RM_GET_OBJECT("column_files_list_group"));
    1702  remminamain->column_files_list_server = GTK_TREE_VIEW_COLUMN(RM_GET_OBJECT("column_files_list_server"));
    1703  remminamain->column_files_list_plugin = GTK_TREE_VIEW_COLUMN(RM_GET_OBJECT("column_files_list_plugin"));
    1704  remminamain->column_files_list_date = GTK_TREE_VIEW_COLUMN(RM_GET_OBJECT("column_files_list_date"));
    1705  remminamain->column_files_list_notes = GTK_TREE_VIEW_COLUMN(RM_GET_OBJECT("column_files_list_notes"));
    1706  gtk_tree_view_column_set_fixed_width(remminamain->column_files_list_notes, 100);
    1707  remminamain->statusbar_main = GTK_STATUSBAR(RM_GET_OBJECT("statusbar_main"));
    1708  /* signals */
    1709  g_signal_connect(remminamain->entry_quick_connect_server, "key-release-event", G_CALLBACK(remmina_main_search_key_event), NULL);
    1710  g_signal_connect(remminamain->tree_files_list, "row-activated", G_CALLBACK(remmina_main_tree_row_activated), NULL);
    1711  /* Non widget objects */
    1712  actions = g_simple_action_group_new();
    1713  g_action_map_add_action_entries(G_ACTION_MAP(actions), app_actions, G_N_ELEMENTS(app_actions), remminamain->window);
    1714  gtk_widget_insert_action_group(GTK_WIDGET(remminamain->window), "app", G_ACTION_GROUP(actions));
    1715  g_action_map_add_action_entries(G_ACTION_MAP(actions), main_actions, G_N_ELEMENTS(main_actions), remminamain->window);
    1716  gtk_widget_insert_action_group(GTK_WIDGET(remminamain->window), "main", G_ACTION_GROUP(actions));
    1717  g_object_unref(actions);
    1718  /* Accelerators */
    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,
    1722  g_cclosure_new_swap(G_CALLBACK(remmina_main_on_action_application_quit), NULL, NULL));
    1723  // TODO: This crash remmina because the function doesn't receive the parameter we expect
    1724  gtk_accel_group_connect(accel_group, GDK_KEY_P, GDK_CONTROL_MASK, 0,
    1725  g_cclosure_new_swap(G_CALLBACK(remmina_main_on_accel_application_preferences), NULL, NULL));
    1726  gtk_accel_group_connect(accel_group, GDK_KEY_F, GDK_CONTROL_MASK, 0,
    1727  g_cclosure_new_swap(G_CALLBACK(remmina_main_on_accel_search_toggle), remminamain, NULL));
    1728 
    1729  /* Connect signals */
    1730  gtk_builder_connect_signals(remminamain->builder, NULL);
    1731  /* Initialize the window and load the preferences */
    1733  return GTK_WIDGET(remminamain->window);
    1734 }
    1735 
    1737 {
    1738  if (!remminamain)
    1739  return NULL;
    1740  if (!remminamain->priv)
    1741  return NULL;
    1742  if (!remminamain->priv->initialized)
    1743  return NULL;
    1744  remminamain->window = GTK_WINDOW(RM_GET_OBJECT("RemminaMain"));
    1745  return remminamain->window;
    1746 }
    1747 
    1749 {
    1750  if (!remminamain)
    1751  return;
    1753 }
    1754 
    1755 void remmina_main_show_dialog(GtkMessageType msg, GtkButtonsType buttons, const gchar* message) {
    1756  GtkWidget *dialog;
    1757 
    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);
    1762  }
    1763 }
    1764 
    1765 void remmina_main_show_warning_dialog(const gchar *message) {
    1766  GtkWidget *dialog;
    1767 
    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);
    1773  }
    1774 }
    G_BEGIN_DECLS struct _RemminaGroupData RemminaGroupData
    RemminaFile * remmina_file_load(const gchar *filename)
    Definition: remmina_file.c:350
    static RemminaSecretPlugin * remmina_secret_plugin
    void remmina_log_start(void)
    Definition: remmina_log.c:116
    @@ -100,11 +100,11 @@ $(document).ready(function(){initNavTree('remmina__main_8c_source.html','');});
    GtkRadioMenuItem * menuitem_view_mode_list
    Definition: remmina_main.h:56
    static void remmina_main_load_file_tree_callback(RemminaFile *remminafile, gpointer user_data)
    Definition: remmina_main.c:483
    -
    void remmina_main_on_action_help_homepage(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_help_homepage(GSimpleAction *action, GVariant *param, gpointer data)
    GtkWidget * network_icon
    Definition: remmina_main.h:82
    gint default_action
    Definition: remmina_pref.h:141
    static void remmina_main_show_snap_welcome()
    Definition: remmina_main.c:272
    -
    GtkWindow * remmina_main_get_window()
    +
    GtkWindow * remmina_main_get_window()
    gchar * selected_filename
    Definition: remmina_main.h:96
    GtkTreeModel * file_model
    Definition: remmina_main.h:90
    static void remmina_main_save_expanded_group(void)
    Definition: remmina_main.c:164
    @@ -126,7 +126,7 @@ $(document).ready(function(){initNavTree('remmina__main_8c_source.html','');});
    void remmina_widget_pool_register(GtkWidget *widget)
    gchar * last_quickconnect_protocol
    Definition: remmina_pref.h:227
    -
    gboolean remmina_main_file_list_on_button_press(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
    +
    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)
    Definition: plugin.h:108
    static gboolean remmina_main_filter_visible_func(GtkTreeModel *model, GtkTreeIter *iter, gpointer user_data)
    Definition: remmina_main.c:527
    @@ -138,7 +138,7 @@ $(document).ready(function(){initNavTree('remmina__main_8c_source.html','');});
    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)
    Definition: remmina_main.c:870
    -
    void remmina_main_on_action_tools_import(GSimpleAction *action, GVariant *param, gpointer 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)
    @@ -158,8 +158,8 @@ $(document).ready(function(){initNavTree('remmina__main_8c_source.html','');});
    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)
    Definition: remmina_main.c:515
    -
    GtkWidget * remmina_main_new(void)
    -
    void remmina_main_on_action_help_debug(GSimpleAction *action, GVariant *param, gpointer 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
    Definition: remmina_main.h:64
    @@ -175,30 +175,30 @@ $(document).ready(function(){initNavTree('remmina__main_8c_source.html','');});
    static gboolean remmina_main_load_file_tree_find(GtkTreeModel *tree, GtkTreeIter *iter, const gchar *match_group)
    Definition: remmina_main.c:455
    gchar * selected_name
    Definition: remmina_main.h:97
    -
    void remmina_main_on_action_help_wiki(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_help_wiki(GSimpleAction *action, GVariant *param, gpointer data)
    RemminaMonitor * monitor
    Definition: remmina_main.h:86
    gint main_sort_order
    Definition: remmina_pref.h:221
    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)
    Definition: remmina_main.c:762
    -
    gboolean remmina_main_on_window_state_event(GtkWidget *widget, GdkEventWindowState *event, 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)
    +
    void remmina_main_update_file_datetime(RemminaFile *file)
    GtkMenuButton * menu_header_button
    Definition: remmina_main.h:53
    static void remmina_main_load_file_tree_group(GtkTreeStore *store)
    Definition: remmina_main.c:407
    void remmina_main_on_action_connection_copy(GSimpleAction *action, GVariant *param, gpointer data)
    Definition: remmina_main.c:910
    void remmina_plugin_manager_show(GtkWindow *parent)
    -
    static void remmina_main_import_file_list(GSList *files)
    +
    static void remmina_main_import_file_list(GSList *files)
    -
    void remmina_main_on_action_collapse(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_collapse(GSimpleAction *action, GVariant *param, gpointer data)
    GtkMenu * menu_popup
    Definition: remmina_main.h:52
    gboolean remmina_main_idle_destroy(gpointer data)
    Definition: remmina_main.c:235
    static gboolean remmina_main_tree_row_activated(GtkTreeView *tree, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data)
    Definition: remmina_main.c:881
    -
    void remmina_main_on_action_help_donations(GSimpleAction *action, GVariant *param, gpointer 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)
    +
    void remmina_main_show_dialog(GtkMessageType msg, GtkButtonsType buttons, const gchar *message)
    gboolean initialized
    Definition: remmina_main.h:94
    @@ -207,11 +207,11 @@ $(document).ready(function(){initNavTree('remmina__main_8c_source.html','');});
    gboolean prevent_snap_welcome_message
    Definition: remmina_pref.h:226
    gchar * expanded_group
    Definition: remmina_pref.h:222
    GtkBox * box_quick_connect
    Definition: remmina_main.h:69
    -
    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)
    +
    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
    Definition: remmina_main.h:77
    -
    void remmina_main_show_warning_dialog(const gchar *message)
    +
    void remmina_main_show_warning_dialog(const gchar *message)
    void remmina_main_on_action_connection_new(GSimpleAction *action, GVariant *param, gpointer data)
    Definition: remmina_main.c:851
    -
    void remmina_main_quick_search_enter(GtkWidget *widget, gpointer user_data)
    +
    void remmina_main_quick_search_enter(GtkWidget *widget, gpointer user_data)
    void remmina_file_delete(const gchar *filename)
    Definition: remmina_file.c:911
    GtkButton * button_new
    Definition: remmina_main.h:60
    GtkMenu * menu_popup_full
    Definition: remmina_main.h:54
    @@ -221,33 +221,33 @@ $(document).ready(function(){initNavTree('remmina__main_8c_source.html','');});
    gboolean main_maximize
    Definition: remmina_pref.h:219
    GtkStatusbar * statusbar_main
    Definition: remmina_main.h:81
    GtkTreeViewColumn * column_files_list_plugin
    Definition: remmina_main.h:78
    -
    void remmina_main_quick_search_on_changed(GtkEditable *editable, gpointer user_data)
    +
    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 * builder
    Definition: remmina_main.h:49
    GtkBuilder * remmina_public_gtk_builder_new_from_resource(gchar *resource)
    void remmina_main_on_action_connection_delete(GSimpleAction *action, GVariant *param, gpointer data)
    Definition: remmina_main.c:977
    -
    static gboolean is_empty(const gchar *s)
    +
    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)
    gint view_file_mode
    Definition: remmina_pref.h:213
    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)
    +
    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)
    Definition: remmina_main.c:150
    -
    void remmina_main_on_show(GtkWidget *w, gpointer user_data)
    -
    static void remmina_main_init(void)
    +
    void remmina_main_on_show(GtkWidget *w, gpointer user_data)
    +
    static void remmina_main_init(void)
    GtkTreeView * tree_files_list
    Definition: remmina_main.h:74
    static void remmina_main_select_file(const gchar *filename)
    Definition: remmina_main.c:618
    gboolean remmina_main_on_delete_event(GtkWidget *widget, GdkEvent *event, gpointer user_data)
    Definition: remmina_main.c:225
    -
    void remmina_main_on_action_help_community(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_help_community(GSimpleAction *action, GVariant *param, gpointer data)
    GtkToggleButton * view_toggle_button
    Definition: remmina_main.h:65
    void remmina_main_destroy()
    Definition: remmina_main.c:193
    RemminaFile * remmina_file_new(void)
    Definition: remmina_file.c:93
    GtkTreeViewColumn * column_files_list_group
    Definition: remmina_main.h:76
    -
    void remmina_main_file_list_on_row_activated(GtkTreeView *tree, GtkTreePath *path, GtkTreeViewColumn *column, gpointer user_data)
    +
    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)
    Definition: remmina_main.c:417
    RemminaStringArray * expanded_group
    Definition: remmina_main.h:99
    static gboolean remmina_main_selection_func(GtkTreeSelection *selection, GtkTreeModel *model, GtkTreePath *path, gboolean path_currently_selected, gpointer user_data)
    Definition: remmina_main.c:322
    @@ -257,26 +257,27 @@ $(document).ready(function(){initNavTree('remmina__main_8c_source.html','');});
    void rcw_open_from_file(RemminaFile *remminafile)
    Definition: rcw.c:4446
    void remmina_main_on_date_column_sort_clicked()
    RemminaPref remmina_pref
    Definition: rcw.c:79
    -
    gboolean remmina_main_file_list_on_key_press(GtkWidget *widget, GdkEventKey *event, gpointer user_data)
    +
    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)
    Definition: remmina_file.c:603
    -
    void remmina_main_on_action_application_dark_theme(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_application_dark_theme(GSimpleAction *action, GVariant *param, gpointer data)
    void remmina_about_open(GtkWindow *parent)
    Definition: remmina_about.c:44
    -
    GtkWidget * remmina_file_editor_new(void)
    +
    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)
    +
    static gboolean remmina_main_add_tool_plugin(gchar *name, RemminaPlugin *plugin, gpointer user_data)
    gboolean remmina_pref_save(void)
    Definition: remmina_pref.c:778
    void remmina_main_on_action_connection_edit(GSimpleAction *action, GVariant *param, gpointer data)
    Definition: remmina_main.c:946
    +
    void remmina_main_toggle_password_view(GtkWidget *widget, gpointer data)
    GtkTreeModel * file_model_sort
    Definition: remmina_main.h:92
    gboolean rcw_open_from_filename(const gchar *filename)
    Definition: rcw.c:4398
    static const gchar * supported_mime_types[]
    Definition: remmina_main.c:87
    -
    void remmina_main_on_action_expand(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_expand(GSimpleAction *action, GVariant *param, gpointer data)
    gboolean(* export_func)(struct _RemminaFilePlugin *instance, RemminaFile *file, const gchar *to_file)
    Definition: plugin.h:110
    gboolean kioskmode
    Definition: remmina.c:87
    GtkWindow * window
    Definition: remmina_main.h:50
    @@ -285,13 +286,13 @@ $(document).ready(function(){initNavTree('remmina__main_8c_source.html','');});
    static char * quick_connect_plugin_list[]
    Definition: remmina_main.c:131
    void remmina_file_save(RemminaFile *remminafile)
    Definition: remmina_file.c:730
    GtkTreeViewColumn * column_files_list_notes
    Definition: remmina_main.h:80
    -
    static gboolean remmina_main_quickconnect(void)
    +
    static gboolean remmina_main_quickconnect(void)
    gboolean always_show_notes
    Definition: remmina_pref.h:153
    void remmina_string_array_add(RemminaStringArray *array, const gchar *str)
    static GtkTargetEntry remmina_drop_types[]
    Definition: remmina_main.c:126
    GtkSearchBar * search_bar
    Definition: remmina_main.h:67
    static RemminaMain * remminamain
    Definition: remmina_main.c:69
    -
    GtkWidget * remmina_file_editor_new_copy(const gchar *filename)
    +
    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
    Definition: remmina_main.h:71
    gint remmina_unlock_new(GtkWindow *parent)
    @@ -303,24 +304,24 @@ $(document).ready(function(){initNavTree('remmina__main_8c_source.html','');});
    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)
    +
    void remmina_main_on_action_search_toggle(GSimpleAction *action, GVariant *param, gpointer data)
    gboolean override_view_file_mode_to_list
    Definition: remmina_main.h:98
    -
    void remmina_main_on_action_tools_export(GSimpleAction *action, GVariant *param, gpointer data)
    +
    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)
    Definition: remmina_main.c:805
    gint remmina_file_manager_iterate(GFunc func, gpointer user_data)
    gboolean dark_theme
    Definition: remmina_pref.h:149
    static void remmina_main_expand_group(void)
    Definition: remmina_main.c:446
    -
    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)
    +
    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()
    Definition: remmina_main.c:646
    GtkTreeViewColumn * column_files_list_date
    Definition: remmina_main.h:79
    -
    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)
    +
    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.
    Definition: remmina_main.c:218
    -
    gboolean remmina_main_quickconnect_on_click(GtkWidget *widget, gpointer user_data)
    +
    gboolean remmina_main_quickconnect_on_click(GtkWidget *widget, gpointer user_data)
    diff --git a/public/remmina__main_8h.html b/public/remmina__main_8h.html index ef0ac5a7c..a37c379b2 100644 --- a/public/remmina__main_8h.html +++ b/public/remmina__main_8h.html @@ -175,6 +175,8 @@ Functions   void remmina_main_on_action_search_toggle (GSimpleAction *action, GVariant *param, gpointer data)   +void remmina_main_toggle_password_view (GtkWidget *widget, gpointer data) +  void remmina_main_reload_preferences ()   @@ -246,7 +248,7 @@ Functions
    -

    Definition at line 1718 of file remmina_main.c.

    +

    Definition at line 1736 of file remmina_main.c.

    @@ -266,7 +268,7 @@ Functions
    -

    Definition at line 1634 of file remmina_main.c.

    +

    Definition at line 1652 of file remmina_main.c.

    @@ -302,7 +304,7 @@ Functions
    -

    Definition at line 1309 of file remmina_main.c.

    +

    Definition at line 1327 of file remmina_main.c.

    @@ -338,7 +340,7 @@ Functions
    -

    Definition at line 1263 of file remmina_main.c.

    +

    Definition at line 1281 of file remmina_main.c.

    @@ -446,7 +448,7 @@ Functions
    -

    Definition at line 1257 of file remmina_main.c.

    +

    Definition at line 1275 of file remmina_main.c.

    @@ -554,7 +556,7 @@ Functions
    -

    Definition at line 1396 of file remmina_main.c.

    +

    Definition at line 1414 of file remmina_main.c.

    @@ -842,7 +844,7 @@ Functions
    -

    Definition at line 1425 of file remmina_main.c.

    +

    Definition at line 1443 of file remmina_main.c.

    @@ -878,7 +880,7 @@ Functions
    -

    Definition at line 1291 of file remmina_main.c.

    +

    Definition at line 1309 of file remmina_main.c.

    @@ -914,7 +916,7 @@ Functions
    -

    Definition at line 1303 of file remmina_main.c.

    +

    Definition at line 1321 of file remmina_main.c.

    @@ -950,7 +952,7 @@ Functions
    -

    Definition at line 1297 of file remmina_main.c.

    +

    Definition at line 1315 of file remmina_main.c.

    @@ -986,7 +988,7 @@ Functions
    -

    Definition at line 1279 of file remmina_main.c.

    +

    Definition at line 1297 of file remmina_main.c.

    @@ -1022,7 +1024,7 @@ Functions
    -

    Definition at line 1285 of file remmina_main.c.

    +

    Definition at line 1303 of file remmina_main.c.

    @@ -1058,7 +1060,7 @@ Functions
    -

    Definition at line 1402 of file remmina_main.c.

    +

    Definition at line 1420 of file remmina_main.c.

    @@ -1094,7 +1096,7 @@ Functions
    -

    Definition at line 1228 of file remmina_main.c.

    +

    Definition at line 1246 of file remmina_main.c.

    @@ -1130,7 +1132,7 @@ Functions
    -

    Definition at line 1216 of file remmina_main.c.

    +

    Definition at line 1234 of file remmina_main.c.

    @@ -1230,7 +1232,7 @@ Functions
    -

    Definition at line 1737 of file remmina_main.c.

    +

    Definition at line 1755 of file remmina_main.c.

    @@ -1250,7 +1252,37 @@ Functions
    -

    Definition at line 1747 of file remmina_main.c.

    +

    Definition at line 1765 of file remmina_main.c.

    + +
    + + +

    ◆ remmina_main_toggle_password_view()

    + +
    +
    + + + + + + + + + + + + + + + + + + +
    void remmina_main_toggle_password_view (GtkWidget * widget,
    gpointer data 
    )
    +
    + +

    Definition at line 1161 of file remmina_main.c.

    @@ -1270,7 +1302,7 @@ Functions
    -

    Definition at line 1730 of file remmina_main.c.

    +

    Definition at line 1748 of file remmina_main.c.

    diff --git a/public/remmina__main_8h.js b/public/remmina__main_8h.js index 470985bce..3cc2f4545 100644 --- a/public/remmina__main_8h.js +++ b/public/remmina__main_8h.js @@ -36,5 +36,6 @@ var remmina__main_8h = [ "remmina_main_save_before_destroy", "remmina__main_8h.html#a95cedb0d631aacbd1b4a5ee1e10a40a5", null ], [ "remmina_main_show_dialog", "remmina__main_8h.html#ab2a1a54320992fb796850ffbd6a63589", null ], [ "remmina_main_show_warning_dialog", "remmina__main_8h.html#ad99b9c0bf2fa8c166a8b4a09e06ffdf7", null ], + [ "remmina_main_toggle_password_view", "remmina__main_8h.html#aac3fe305e456dfa7bb55aa2f057e8cb0", null ], [ "remmina_main_update_file_datetime", "remmina__main_8h.html#a5ae0372dafe41f96a09097c07d1b270a", null ] ]; \ No newline at end of file diff --git a/public/remmina__main_8h_source.html b/public/remmina__main_8h_source.html index 9bd1d24fa..451dbcae3 100644 --- a/public/remmina__main_8h_source.html +++ b/public/remmina__main_8h_source.html @@ -86,7 +86,7 @@ $(document).ready(function(){initNavTree('remmina__main_8h_source.html','');});
    remmina_main.h
    -Go to the documentation of this file.
    1 /*
    2  * Remmina - The GTK+ Remote Desktop Client
    3  * Copyright (C) 2009-2011 Vic Lee
    4  * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
    5  * Copyright (C) 2016-2022 Antenore Gatta, Giovanni Panozzo
    6  * Copyright (C) 2022-2023 Antenore Gatta, Giovanni Panozzo, Hiroyuki Tanaka
    7  *
    8  * This program is free software; you can redistribute it and/or modify
    9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    16  * GNU General Public License for more details.
    17  *
    18  * You should have received a copy of the GNU General Public License
    19  * along with this program; if not, write to the Free Software
    20  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
    21  * Boston, MA 02110-1301, USA.
    22  *
    23  * In addition, as a special exception, the copyright holders give
    24  * permission to link the code of portions of this program with the
    25  * OpenSSL library under certain conditions as described in each
    26  * individual source file, and distribute linked combinations
    27  * including the two.
    28  * You must obey the GNU General Public License in all respects
    29  * for all of the code used other than OpenSSL. * If you modify
    30  * file(s) with this exception, you may extend this exception to your
    31  * version of the file(s), but you are not obligated to do so. * If you
    32  * do not wish to do so, delete this exception statement from your
    33  * version. * If you delete this exception statement from all source
    34  * files in the program, then also delete it here.
    35  *
    36  */
    37 
    38 #pragma once
    39 
    40 #include "remmina_file.h"
    41 #include "remmina_monitor.h"
    42 #include <gtk/gtk.h>
    43 
    44 #include "remmina_string_array.h"
    45 
    47 
    48 typedef struct _RemminaMain {
    49  GtkBuilder * builder;
    50  GtkWindow * window;
    51  /* Menu widgets */
    52  GtkMenu * menu_popup;
    53  GtkMenuButton * menu_header_button;
    54  GtkMenu * menu_popup_full;
    56  GtkRadioMenuItem * menuitem_view_mode_list;
    57  GtkRadioMenuItem * menuitem_view_mode_tree;
    58  GtkMenuItem * menuitem_connection_quit;
    59  /* Button new */
    60  GtkButton * button_new;
    61  GtkButton * button_make_default;
    62  /* Search bar objects */
    63  GtkToggleButton * search_toggle;
    64  GtkSwitch * switch_dark_mode;
    65  GtkToggleButton * view_toggle_button;
    66  GtkToggleButton * ustats_toggle;
    67  GtkSearchBar * search_bar;
    68  /* Quick connect objects */
    70  GtkComboBoxText * combo_quick_connect_protocol;
    72  GtkButton * button_quick_connect;
    73  /* Other widgets */
    74  GtkTreeView * tree_files_list;
    75  GtkTreeViewColumn * column_files_list_name;
    76  GtkTreeViewColumn * column_files_list_group;
    77  GtkTreeViewColumn * column_files_list_server;
    78  GtkTreeViewColumn * column_files_list_plugin;
    79  GtkTreeViewColumn * column_files_list_date;
    80  GtkTreeViewColumn * column_files_list_notes;
    81  GtkStatusbar * statusbar_main;
    82  GtkWidget * network_icon;
    83  /* Non widget objects */
    84  GtkAccelGroup * accelgroup_shortcuts;
    87 } RemminaMain;
    88 
    90  GtkTreeModel * file_model;
    91  GtkTreeModel * file_model_filter;
    92  GtkTreeModel * file_model_sort;
    93 
    94  gboolean initialized;
    95 
    97  gchar * selected_name;
    100 };
    101 
    102 G_BEGIN_DECLS
    103 
    104 /* Create the remminamain struct and the remmina main Remmina window */
    105 GtkWidget *remmina_main_new(void);
    106 /* Get the current main GTK window or NULL if not initialized */
    107 GtkWindow *remmina_main_get_window(void);
    108 
    110 
    111 void remmina_main_destroy(void);
    114 
    115 void remmina_main_show_dialog(GtkMessageType msg, GtkButtonsType buttons, const gchar* message);
    116 void remmina_main_show_warning_dialog(const gchar *message);
    117 void remmina_main_on_action_application_about(GSimpleAction *action, GVariant *param, gpointer data);
    118 void remmina_main_on_action_application_default(GSimpleAction *action, GVariant *param, gpointer data);
    119 void remmina_main_on_action_application_mpchange(GSimpleAction *action, GVariant *param, gpointer data);
    120 void remmina_main_on_action_application_plugins(GSimpleAction *action, GVariant *param, gpointer data);
    121 void remmina_main_on_action_application_dark_theme(GSimpleAction *action, GVariant *param, gpointer data);
    122 void remmina_main_on_action_application_preferences(GSimpleAction *action, GVariant *param, gpointer data);
    123 void remmina_main_on_action_application_quit(GSimpleAction *action, GVariant *param, gpointer data);
    124 void remmina_main_on_action_connection_connect(GSimpleAction *action, GVariant *param, gpointer data);
    125 void remmina_main_on_action_connection_copy(GSimpleAction *action, GVariant *param, gpointer data);
    126 void remmina_main_on_action_connection_delete(GSimpleAction *action, GVariant *param, gpointer data);
    127 void remmina_main_on_action_connection_delete_multiple(GSimpleAction *action, GVariant *param, gpointer data);
    128 void remmina_main_on_action_connection_edit(GSimpleAction *action, GVariant *param, gpointer data);
    129 void remmina_main_on_action_connection_external_tools(GSimpleAction *action, GVariant *param, gpointer data);
    130 void remmina_main_on_action_connection_new(GSimpleAction *action, GVariant *param, gpointer data);
    131 void remmina_main_on_action_help_community(GSimpleAction *action, GVariant *param, gpointer data);
    132 void remmina_main_on_action_help_debug(GSimpleAction *action, GVariant *param, gpointer data);
    133 void remmina_main_on_action_help_donations(GSimpleAction *action, GVariant *param, gpointer data);
    134 void remmina_main_on_action_help_homepage(GSimpleAction *action, GVariant *param, gpointer data);
    135 void remmina_main_on_action_help_wiki(GSimpleAction *action, GVariant *param, gpointer data);
    136 void remmina_main_on_action_tools_export(GSimpleAction *action, GVariant *param, gpointer data);
    137 void remmina_main_on_action_tools_import(GSimpleAction *action, GVariant *param, gpointer data);
    138 void remmina_main_on_action_expand(GSimpleAction *action, GVariant *param, gpointer data);
    139 void remmina_main_on_action_collapse(GSimpleAction *action, GVariant *param, gpointer data);
    140 void remmina_main_on_action_search_toggle(GSimpleAction *action, GVariant *param, gpointer data);
    142 
    143 G_END_DECLS
    void remmina_main_on_action_application_plugins(GSimpleAction *action, GVariant *param, gpointer data)
    +Go to the documentation of this file.
    1 /*
    2  * Remmina - The GTK+ Remote Desktop Client
    3  * Copyright (C) 2009-2011 Vic Lee
    4  * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
    5  * Copyright (C) 2016-2022 Antenore Gatta, Giovanni Panozzo
    6  * Copyright (C) 2022-2023 Antenore Gatta, Giovanni Panozzo, Hiroyuki Tanaka
    7  *
    8  * This program is free software; you can redistribute it and/or modify
    9  * it under the terms of the GNU General Public License as published by
    10  * the Free Software Foundation; either version 2 of the License, or
    11  * (at your option) any later version.
    12  *
    13  * This program is distributed in the hope that it will be useful,
    14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    16  * GNU General Public License for more details.
    17  *
    18  * You should have received a copy of the GNU General Public License
    19  * along with this program; if not, write to the Free Software
    20  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
    21  * Boston, MA 02110-1301, USA.
    22  *
    23  * In addition, as a special exception, the copyright holders give
    24  * permission to link the code of portions of this program with the
    25  * OpenSSL library under certain conditions as described in each
    26  * individual source file, and distribute linked combinations
    27  * including the two.
    28  * You must obey the GNU General Public License in all respects
    29  * for all of the code used other than OpenSSL. * If you modify
    30  * file(s) with this exception, you may extend this exception to your
    31  * version of the file(s), but you are not obligated to do so. * If you
    32  * do not wish to do so, delete this exception statement from your
    33  * version. * If you delete this exception statement from all source
    34  * files in the program, then also delete it here.
    35  *
    36  */
    37 
    38 #pragma once
    39 
    40 #include "remmina_file.h"
    41 #include "remmina_monitor.h"
    42 #include <gtk/gtk.h>
    43 
    44 #include "remmina_string_array.h"
    45 
    47 
    48 typedef struct _RemminaMain {
    49  GtkBuilder * builder;
    50  GtkWindow * window;
    51  /* Menu widgets */
    52  GtkMenu * menu_popup;
    53  GtkMenuButton * menu_header_button;
    54  GtkMenu * menu_popup_full;
    56  GtkRadioMenuItem * menuitem_view_mode_list;
    57  GtkRadioMenuItem * menuitem_view_mode_tree;
    58  GtkMenuItem * menuitem_connection_quit;
    59  /* Button new */
    60  GtkButton * button_new;
    61  GtkButton * button_make_default;
    62  /* Search bar objects */
    63  GtkToggleButton * search_toggle;
    64  GtkSwitch * switch_dark_mode;
    65  GtkToggleButton * view_toggle_button;
    66  GtkToggleButton * ustats_toggle;
    67  GtkSearchBar * search_bar;
    68  /* Quick connect objects */
    70  GtkComboBoxText * combo_quick_connect_protocol;
    72  GtkButton * button_quick_connect;
    73  /* Other widgets */
    74  GtkTreeView * tree_files_list;
    75  GtkTreeViewColumn * column_files_list_name;
    76  GtkTreeViewColumn * column_files_list_group;
    77  GtkTreeViewColumn * column_files_list_server;
    78  GtkTreeViewColumn * column_files_list_plugin;
    79  GtkTreeViewColumn * column_files_list_date;
    80  GtkTreeViewColumn * column_files_list_notes;
    81  GtkStatusbar * statusbar_main;
    82  GtkWidget * network_icon;
    83  /* Non widget objects */
    84  GtkAccelGroup * accelgroup_shortcuts;
    87 } RemminaMain;
    88 
    90  GtkTreeModel * file_model;
    91  GtkTreeModel * file_model_filter;
    92  GtkTreeModel * file_model_sort;
    93 
    94  gboolean initialized;
    95 
    97  gchar * selected_name;
    100 };
    101 
    102 G_BEGIN_DECLS
    103 
    104 /* Create the remminamain struct and the remmina main Remmina window */
    105 GtkWidget *remmina_main_new(void);
    106 /* Get the current main GTK window or NULL if not initialized */
    107 GtkWindow *remmina_main_get_window(void);
    108 
    110 
    111 void remmina_main_destroy(void);
    114 
    115 void remmina_main_show_dialog(GtkMessageType msg, GtkButtonsType buttons, const gchar* message);
    116 void remmina_main_show_warning_dialog(const gchar *message);
    117 void remmina_main_on_action_application_about(GSimpleAction *action, GVariant *param, gpointer data);
    118 void remmina_main_on_action_application_default(GSimpleAction *action, GVariant *param, gpointer data);
    119 void remmina_main_on_action_application_mpchange(GSimpleAction *action, GVariant *param, gpointer data);
    120 void remmina_main_on_action_application_plugins(GSimpleAction *action, GVariant *param, gpointer data);
    121 void remmina_main_on_action_application_dark_theme(GSimpleAction *action, GVariant *param, gpointer data);
    122 void remmina_main_on_action_application_preferences(GSimpleAction *action, GVariant *param, gpointer data);
    123 void remmina_main_on_action_application_quit(GSimpleAction *action, GVariant *param, gpointer data);
    124 void remmina_main_on_action_connection_connect(GSimpleAction *action, GVariant *param, gpointer data);
    125 void remmina_main_on_action_connection_copy(GSimpleAction *action, GVariant *param, gpointer data);
    126 void remmina_main_on_action_connection_delete(GSimpleAction *action, GVariant *param, gpointer data);
    127 void remmina_main_on_action_connection_delete_multiple(GSimpleAction *action, GVariant *param, gpointer data);
    128 void remmina_main_on_action_connection_edit(GSimpleAction *action, GVariant *param, gpointer data);
    129 void remmina_main_on_action_connection_external_tools(GSimpleAction *action, GVariant *param, gpointer data);
    130 void remmina_main_on_action_connection_new(GSimpleAction *action, GVariant *param, gpointer data);
    131 void remmina_main_on_action_help_community(GSimpleAction *action, GVariant *param, gpointer data);
    132 void remmina_main_on_action_help_debug(GSimpleAction *action, GVariant *param, gpointer data);
    133 void remmina_main_on_action_help_donations(GSimpleAction *action, GVariant *param, gpointer data);
    134 void remmina_main_on_action_help_homepage(GSimpleAction *action, GVariant *param, gpointer data);
    135 void remmina_main_on_action_help_wiki(GSimpleAction *action, GVariant *param, gpointer data);
    136 void remmina_main_on_action_tools_export(GSimpleAction *action, GVariant *param, gpointer data);
    137 void remmina_main_on_action_tools_import(GSimpleAction *action, GVariant *param, gpointer data);
    138 void remmina_main_on_action_expand(GSimpleAction *action, GVariant *param, gpointer data);
    139 void remmina_main_on_action_collapse(GSimpleAction *action, GVariant *param, gpointer data);
    140 void remmina_main_on_action_search_toggle(GSimpleAction *action, GVariant *param, gpointer data);
    141 void remmina_main_toggle_password_view(GtkWidget *widget, gpointer data);
    143 
    144 G_END_DECLS
    void remmina_main_on_action_application_plugins(GSimpleAction *action, GVariant *param, gpointer data)
    GtkToggleButton * search_toggle
    Definition: remmina_main.h:63
    GtkRadioMenuItem * menuitem_view_mode_list
    Definition: remmina_main.h:56
    GtkWidget * network_icon
    Definition: remmina_main.h:82
    @@ -97,7 +97,7 @@ $(document).ready(function(){initNavTree('remmina__main_8h_source.html','');});
    GtkTreeModel * file_model
    Definition: remmina_main.h:90
    void remmina_main_destroy(void)
    Definition: remmina_main.c:193
    RemminaMainPriv * priv
    Definition: remmina_main.h:85
    -
    void remmina_main_on_action_help_homepage(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_help_homepage(GSimpleAction *action, GVariant *param, gpointer data)
    typedefG_BEGIN_DECLS struct _RemminaFile RemminaFile
    Definition: types.h:44
    GtkMenuItem * menuitem_connection_quit
    Definition: remmina_main.h:58
    GtkRadioMenuItem * menuitem_view_mode_tree
    Definition: remmina_main.h:57
    @@ -105,22 +105,22 @@ $(document).ready(function(){initNavTree('remmina__main_8h_source.html','');});
    GtkMenu * menu_popup_delete_rc
    Definition: remmina_main.h:55
    -
    void remmina_main_on_action_expand(GSimpleAction *action, GVariant *param, gpointer data)
    -
    void remmina_main_on_action_help_debug(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_expand(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_help_debug(GSimpleAction *action, GVariant *param, gpointer data)
    void remmina_main_on_action_connection_copy(GSimpleAction *action, GVariant *param, gpointer data)
    Definition: remmina_main.c:910
    -
    G_BEGIN_DECLS GtkWidget * remmina_main_new(void)
    -
    void remmina_main_on_action_tools_import(GSimpleAction *action, GVariant *param, gpointer data)
    +
    G_BEGIN_DECLS GtkWidget * remmina_main_new(void)
    +
    void remmina_main_on_action_tools_import(GSimpleAction *action, GVariant *param, gpointer data)
    GtkSwitch * switch_dark_mode
    Definition: remmina_main.h:64
    GtkAccelGroup * accelgroup_shortcuts
    Definition: remmina_main.h:84
    -
    void remmina_main_on_action_application_dark_theme(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_application_dark_theme(GSimpleAction *action, GVariant *param, gpointer data)
    GtkTreeModel * file_model_filter
    Definition: remmina_main.h:91
    gchar * selected_name
    Definition: remmina_main.h:97
    RemminaMonitor * monitor
    Definition: remmina_main.h:86
    void remmina_main_on_action_connection_delete(GSimpleAction *action, GVariant *param, gpointer data)
    Definition: remmina_main.c:977
    -
    void remmina_main_on_action_application_about(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_application_about(GSimpleAction *action, GVariant *param, gpointer data)
    GtkMenuButton * menu_header_button
    Definition: remmina_main.h:53
    -
    void remmina_main_show_dialog(GtkMessageType msg, GtkButtonsType buttons, const gchar *message)
    -
    void remmina_main_on_action_search_toggle(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_show_dialog(GtkMessageType msg, GtkButtonsType buttons, const gchar *message)
    +
    void remmina_main_on_action_search_toggle(GSimpleAction *action, GVariant *param, gpointer data)
    void remmina_main_on_action_application_preferences(GSimpleAction *action, GVariant *param, gpointer data)
    GtkMenu * menu_popup
    Definition: remmina_main.h:52
    void remmina_main_reload_preferences()
    @@ -130,7 +130,7 @@ $(document).ready(function(){initNavTree('remmina__main_8h_source.html','');});
    void remmina_main_on_action_connection_delete_multiple(GSimpleAction *action, GVariant *param, gpointer data)
    GtkBox * box_quick_connect
    Definition: remmina_main.h:69
    GtkTreeViewColumn * column_files_list_server
    Definition: remmina_main.h:77
    -
    void remmina_main_on_action_help_community(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_help_community(GSimpleAction *action, GVariant *param, gpointer data)
    GtkButton * button_new
    Definition: remmina_main.h:60
    GtkMenu * menu_popup_full
    Definition: remmina_main.h:54
    GtkStatusbar * statusbar_main
    Definition: remmina_main.h:81
    @@ -140,30 +140,31 @@ $(document).ready(function(){initNavTree('remmina__main_8h_source.html','');});
    GtkBuilder * builder
    Definition: remmina_main.h:49
    GtkButton * button_quick_connect
    Definition: remmina_main.h:72
    -
    void remmina_main_on_action_tools_export(GSimpleAction *action, GVariant *param, gpointer data)
    -
    GtkWindow * remmina_main_get_window(void)
    +
    void remmina_main_on_action_tools_export(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_toggle_password_view(GtkWidget *widget, gpointer data)
    +
    GtkWindow * remmina_main_get_window(void)
    void remmina_main_on_action_application_mpchange(GSimpleAction *action, GVariant *param, gpointer data)
    Definition: remmina_main.c:814
    GtkTreeView * tree_files_list
    Definition: remmina_main.h:74
    GtkToggleButton * view_toggle_button
    Definition: remmina_main.h:65
    GtkTreeViewColumn * column_files_list_group
    Definition: remmina_main.h:76
    RemminaStringArray * expanded_group
    Definition: remmina_main.h:99
    void remmina_main_on_action_connection_edit(GSimpleAction *action, GVariant *param, gpointer data)
    Definition: remmina_main.c:946
    -
    void remmina_main_show_warning_dialog(const gchar *message)
    +
    void remmina_main_show_warning_dialog(const gchar *message)
    void remmina_main_on_action_application_default(GSimpleAction *action, GVariant *param, gpointer data)
    GtkTreeModel * file_model_sort
    Definition: remmina_main.h:92
    -
    void remmina_main_update_file_datetime(RemminaFile *file)
    +
    void remmina_main_update_file_datetime(RemminaFile *file)
    void remmina_main_on_action_connection_connect(GSimpleAction *action, GVariant *param, gpointer data)
    Definition: remmina_main.c:768
    GtkWindow * window
    Definition: remmina_main.h:50
    void remmina_main_on_action_application_quit(GSimpleAction *action, GVariant *param, gpointer data)
    GtkToggleButton * ustats_toggle
    Definition: remmina_main.h:66
    void remmina_main_on_action_connection_new(GSimpleAction *action, GVariant *param, gpointer data)
    Definition: remmina_main.c:851
    -
    void remmina_main_on_action_collapse(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_collapse(GSimpleAction *action, GVariant *param, gpointer data)
    GtkButton * button_make_default
    Definition: remmina_main.h:61
    -
    void remmina_main_on_action_help_donations(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_help_donations(GSimpleAction *action, GVariant *param, gpointer data)
    GtkTreeViewColumn * column_files_list_notes
    Definition: remmina_main.h:80
    GtkSearchBar * search_bar
    Definition: remmina_main.h:67
    GtkEntry * entry_quick_connect_server
    Definition: remmina_main.h:71
    -
    void remmina_main_on_action_help_wiki(GSimpleAction *action, GVariant *param, gpointer data)
    +
    void remmina_main_on_action_help_wiki(GSimpleAction *action, GVariant *param, gpointer data)
    gboolean override_view_file_mode_to_list
    Definition: remmina_main.h:98
    struct _RemminaMain RemminaMain
    diff --git a/public/remmina__message__panel_8c.html b/public/remmina__message__panel_8c.html index 630bd874d..fcffc0626 100644 --- a/public/remmina__message__panel_8c.html +++ b/public/remmina__message__panel_8c.html @@ -177,7 +177,7 @@ Variables
    -

    Definition at line 54 of file remmina_message_panel.c.

    +

    Definition at line 55 of file remmina_message_panel.c.

    @@ -215,7 +215,7 @@ Variables
    -

    Definition at line 110 of file remmina_message_panel.c.

    +

    Definition at line 111 of file remmina_message_panel.c.

    @@ -243,7 +243,7 @@ Variables
    -

    Definition at line 71 of file remmina_message_panel.c.

    +

    Definition at line 72 of file remmina_message_panel.c.

    @@ -273,7 +273,7 @@ Variables
    -

    Definition at line 775 of file remmina_message_panel.c.

    +

    Definition at line 779 of file remmina_message_panel.c.

    @@ -303,7 +303,7 @@ Variables
    -

    Definition at line 703 of file remmina_message_panel.c.

    +

    Definition at line 707 of file remmina_message_panel.c.

    @@ -333,7 +333,7 @@ Variables
    -

    Definition at line 739 of file remmina_message_panel.c.

    +

    Definition at line 743 of file remmina_message_panel.c.

    @@ -369,7 +369,7 @@ Variables
    -

    Definition at line 758 of file remmina_message_panel.c.

    +

    Definition at line 762 of file remmina_message_panel.c.

    @@ -405,7 +405,7 @@ Variables
    -

    Definition at line 687 of file remmina_message_panel.c.

    +

    Definition at line 691 of file remmina_message_panel.c.

    @@ -441,7 +441,7 @@ Variables
    -

    Definition at line 721 of file remmina_message_panel.c.

    +

    Definition at line 725 of file remmina_message_panel.c.

    @@ -461,7 +461,7 @@ Variables
    -

    Definition at line 652 of file remmina_message_panel.c.

    +

    Definition at line 656 of file remmina_message_panel.c.

    @@ -489,7 +489,7 @@ Variables
    -

    Definition at line 66 of file remmina_message_panel.c.

    +

    Definition at line 67 of file remmina_message_panel.c.

    @@ -509,7 +509,7 @@ Variables
    -

    Definition at line 87 of file remmina_message_panel.c.

    +

    Definition at line 88 of file remmina_message_panel.c.

    @@ -539,7 +539,7 @@ Variables
    -

    Definition at line 793 of file remmina_message_panel.c.

    +

    Definition at line 797 of file remmina_message_panel.c.

    @@ -593,7 +593,7 @@ Variables
    -

    Definition at line 282 of file remmina_message_panel.c.

    +

    Definition at line 283 of file remmina_message_panel.c.

    @@ -629,7 +629,7 @@ Variables
    -

    Definition at line 480 of file remmina_message_panel.c.

    +

    Definition at line 484 of file remmina_message_panel.c.

    @@ -671,7 +671,7 @@ Variables
    -

    Definition at line 174 of file remmina_message_panel.c.

    +

    Definition at line 175 of file remmina_message_panel.c.

    @@ -713,7 +713,7 @@ Variables
    -

    Definition at line 127 of file remmina_message_panel.c.

    +

    Definition at line 128 of file remmina_message_panel.c.

    @@ -755,7 +755,7 @@ Variables
    -

    Definition at line 213 of file remmina_message_panel.c.

    +

    Definition at line 214 of file remmina_message_panel.c.

    @@ -780,7 +780,7 @@ Variables
    -

    Definition at line 64 of file remmina_message_panel.c.

    +

    Definition at line 65 of file remmina_message_panel.c.

    @@ -804,7 +804,7 @@ Variables
    -

    Definition at line 60 of file remmina_message_panel.c.

    +

    Definition at line 61 of file remmina_message_panel.c.

    diff --git a/public/remmina__message__panel_8c_source.html b/public/remmina__message__panel_8c_source.html index 4915b76d7..85f67cf64 100644 --- a/public/remmina__message__panel_8c_source.html +++ b/public/remmina__message__panel_8c_source.html @@ -86,51 +86,53 @@ $(document).ready(function(){initNavTree('remmina__message__panel_8c_source.html
    remmina_message_panel.c
    -Go to the documentation of this file.
    1 /*
    2  * Remmina - The GTK+ Remote Desktop Client
    3  * Copyright (C) 2009-2011 Vic Lee
    4  * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
    5  * Copyright (C) 2016-2023 Antenore Gatta, Giovanni Panozzo
    6  *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    15  * GNU General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
    20  * Boston, MA 02110-1301, USA.
    21  *
    22  * In addition, as a special exception, the copyright holders give
    23  * permission to link the code of portions of this program with the
    24  * OpenSSL library under certain conditions as described in each
    25  * individual source file, and distribute linked combinations
    26  * including the two.
    27  * You must obey the GNU General Public License in all respects
    28  * for all of the code used other than OpenSSL. * If you modify
    29  * file(s) with this exception, you may extend this exception to your
    30  * version of the file(s), but you are not obligated to do so. * If you
    31  * do not wish to do so, delete this exception statement from your
    32  * version. * If you delete this exception statement from all source
    33  * files in the program, then also delete it here.
    34  *
    35  */
    36 
    37 #include <glib/gi18n.h>
    38 #include "config.h"
    39 #include "remmina_public.h"
    40 #include "remmina_widget_pool.h"
    41 #include "remmina_message_panel.h"
    44 
    45 
    46 typedef struct
    47 {
    48 
    52 
    54 G_DEFINE_TYPE_WITH_PRIVATE (RemminaMessagePanel, remmina_message_panel, GTK_TYPE_BOX)
    55 
    56 
    57 enum {
    58  RESPONSE,
    60 };
    61 
    62 static guint messagepanel_signals[LAST_SIGNAL];
    63 
    64 static const gchar btn_response_key[] = "btn_response";
    65 
    66 static void remmina_message_panel_init (RemminaMessagePanel *mp)
    67 {
    68  TRACE_CALL(__func__);
    69 }
    70 
    71 static void remmina_message_panel_class_init(RemminaMessagePanelClass *class)
    72 {
    73  TRACE_CALL(__func__);
    74  // class->transform_text = my_app_label_real_transform_text;
    75 
    76  messagepanel_signals[RESPONSE] =
    77  g_signal_new ("response",
    78  G_OBJECT_CLASS_TYPE (class),
    79  G_SIGNAL_RUN_LAST,
    80  G_STRUCT_OFFSET (RemminaMessagePanelClass, response),
    81  NULL, NULL,
    82  NULL,
    83  G_TYPE_NONE, 1,
    84  G_TYPE_INT);
    85 }
    86 
    87 RemminaMessagePanel *remmina_message_panel_new()
    88 {
    89  TRACE_CALL(__func__);
    91  RemminaMessagePanel* mp;
    92  mp = (RemminaMessagePanel*)g_object_new(REMMINA_TYPE_MESSAGE_PANEL,
    93  "orientation", GTK_ORIENTATION_VERTICAL,
    94  "spacing", 0,
    95  NULL);
    96 
    97  priv = remmina_message_panel_get_instance_private(mp);
    98 
    99  priv->response_callback = NULL;
    100  priv->response_callback_data = NULL;
    101 
    102  /* Set widget class, for CSS styling */
    103  // gtk_widget_set_name(GTK_WIDGET(mp), "remmina-cw-message-panel");
    104  gtk_style_context_add_class(gtk_widget_get_style_context(GTK_WIDGET(mp)), "message_panel");
    105  gtk_style_context_add_class(gtk_widget_get_style_context(GTK_WIDGET(mp)), "background");
    106 
    107  return mp;
    108 }
    109 
    111  GtkButton *button, gpointer user_data)
    112 {
    113  TRACE_CALL(__func__);
    114  RemminaMessagePanel *mp = (RemminaMessagePanel*)user_data;
    115  RemminaMessagePanelPrivate *priv = remmina_message_panel_get_instance_private(mp);
    116 
    117  gint btn_data;
    118 
    119  btn_data = (gint)((gint64)g_object_get_data(G_OBJECT(button), btn_response_key));
    120 
    121  /* Calls the callback, if defined */
    122  if (priv->response_callback != NULL)
    123  (*priv->response_callback)(priv->response_callback_data, btn_data);
    124 
    125 }
    126 
    127 void remmina_message_panel_setup_progress(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    128 {
    129  /*
    130  * Setup a message panel to show a spinner, a message like "Connecting…",
    131  * and a button to cancel the action in progress
    132  *
    133  */
    134 
    135  TRACE_CALL(__func__);
    136  GtkBox *hbox;
    137  GtkWidget *w;
    138  RemminaMessagePanelPrivate *priv = remmina_message_panel_get_instance_private(mp);
    139 
    141  printf("WARNING: %s called in a subthread. This should not happen.\n", __func__);
    142  raise(SIGINT);
    143  }
    144 
    145  hbox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0));
    146 
    147  /* A spinner */
    148  w = gtk_spinner_new();
    149  gtk_box_pack_start(hbox, w, FALSE, FALSE, 0);
    150  gtk_spinner_start(GTK_SPINNER(w));
    151 
    152  /* A message */
    153  w = gtk_label_new(message);
    154  gtk_box_pack_start(hbox, w, TRUE, TRUE, 0);
    155 
    156  priv->response_callback = response_callback;
    157  priv->response_callback_data = response_callback_data;
    158 
    159  /* A button to cancel the action. The cancel button is available
    160  * only when a response_callback function is defined. */
    161  if (response_callback) {
    162  w = gtk_button_new_with_label(_("Cancel"));
    163  gtk_box_pack_end(hbox, w, FALSE, FALSE, 0);
    164  g_object_set_data(G_OBJECT(w), btn_response_key, (void *)GTK_RESPONSE_CANCEL);
    165  g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(remmina_message_panel_button_clicked_callback), mp);
    166  }
    167 
    168  gtk_box_pack_start(GTK_BOX(mp), GTK_WIDGET(hbox), TRUE, TRUE, 0);
    169 
    170  gtk_widget_show_all(GTK_WIDGET(mp));
    171 
    172 }
    173 
    174 void remmina_message_panel_setup_message(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    175 {
    176  /*
    177  * Setup a message panel to a message to read like "Cannot connect…",
    178  * and a button to close the panel
    179  *
    180  */
    181 
    182  TRACE_CALL(__func__);
    183  GtkBox *hbox;
    184  GtkWidget *w;
    185  RemminaMessagePanelPrivate *priv = remmina_message_panel_get_instance_private(mp);
    186 
    188  printf("WARNING: %s called in a subthread. This should not happen.\n", __func__);
    189  }
    190 
    191  hbox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0));
    192 
    193  /* A message */
    194  w = gtk_label_new(message);
    195  gtk_box_pack_start(hbox, w, TRUE, TRUE, 0);
    196 
    197  /* A button to confirm reading */
    198  w = gtk_button_new_with_label(_("Close"));
    199  gtk_box_pack_end(hbox, w, FALSE, FALSE, 0);
    200 
    201  priv->response_callback = response_callback;
    202  priv->response_callback_data = response_callback_data;
    203 
    204  g_object_set_data(G_OBJECT(w), btn_response_key, (void *)GTK_RESPONSE_OK);
    205  g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(remmina_message_panel_button_clicked_callback), mp);
    206 
    207  gtk_box_pack_start(GTK_BOX(mp), GTK_WIDGET(hbox), TRUE, TRUE, 0);
    208 
    209  gtk_widget_show_all(GTK_WIDGET(mp));
    210 
    211 }
    212 
    213 void remmina_message_panel_setup_question(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    214 {
    215  /*
    216  * Setup a message panel to a message to read like "Do you accept ?",
    217  * and a pair of button for Yes and No
    218  * message is an HTML string
    219  * Callback will receive GTK_RESPONSE_NO for No, GTK_RESPONSE_YES for Yes
    220  *
    221  */
    222 
    223  TRACE_CALL(__func__);
    224  GtkWidget *grid;
    225  GtkWidget *bbox;
    226  GtkWidget *w;
    227  RemminaMessagePanelPrivate *priv = remmina_message_panel_get_instance_private(mp);
    228 
    230  printf("WARNING: %s called in a subthread. This should not happen. Raising SIGINT for debugging.\n", __func__);
    231  raise(SIGINT);
    232  }
    233 
    234  /* Create grid */
    235  grid = gtk_grid_new();
    236  gtk_widget_set_halign(GTK_WIDGET(grid), GTK_ALIGN_CENTER);
    237  gtk_widget_set_valign(GTK_WIDGET(grid), GTK_ALIGN_CENTER);
    238  gtk_widget_show(grid);
    239  gtk_grid_set_row_spacing(GTK_GRID(grid), 6);
    240  gtk_grid_set_column_spacing(GTK_GRID(grid), 6);
    241 
    242  /* A message, in HTML format */
    243  w = gtk_label_new(NULL);
    244  gtk_label_set_markup(GTK_LABEL(w), message);
    245 
    246  gtk_widget_set_halign(GTK_WIDGET(w), GTK_ALIGN_START);
    247  gtk_widget_set_valign(GTK_WIDGET(w), GTK_ALIGN_FILL);
    248  gtk_widget_set_margin_top (GTK_WIDGET(w), 18);
    249  gtk_widget_set_margin_bottom (GTK_WIDGET(w), 9);
    250  gtk_widget_set_margin_start (GTK_WIDGET(w), 18);
    251  gtk_widget_set_margin_end (GTK_WIDGET(w), 18);
    252  gtk_widget_show(w);
    253  gtk_grid_attach(GTK_GRID(grid), w, 0, 0, 2, 1);
    254 
    255  /* A button for yes and one for no */
    256  bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
    257  gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_START);
    258  gtk_grid_attach(GTK_GRID(grid), bbox, 0, 1, 1, 1);
    259  w = gtk_button_new_with_label(_("Yes"));
    260  gtk_widget_set_valign(GTK_WIDGET(w), GTK_ALIGN_CENTER);
    261  g_object_set_data(G_OBJECT(w), btn_response_key, (void *)GTK_RESPONSE_YES);
    262 
    263  g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(remmina_message_panel_button_clicked_callback), mp);
    264  gtk_container_add(GTK_CONTAINER(bbox), w);
    265 
    266  w = gtk_button_new_with_label(_("No"));
    267  gtk_widget_set_valign(GTK_WIDGET(w), GTK_ALIGN_CENTER);
    268  g_object_set_data(G_OBJECT(w), btn_response_key, (void *)GTK_RESPONSE_NO);
    269 
    270  priv->response_callback = response_callback;
    271  priv->response_callback_data = response_callback_data;
    272 
    273  g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(remmina_message_panel_button_clicked_callback), mp);
    274  gtk_container_add(GTK_CONTAINER(bbox), w);
    275 
    276  gtk_box_pack_start(GTK_BOX(mp), GTK_WIDGET(grid), TRUE, TRUE, 0);
    277 
    278  gtk_widget_show_all(GTK_WIDGET(mp));
    279 
    280 }
    281 
    282 void remmina_message_panel_setup_auth(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data, const gchar *title, const gchar *password_prompt, unsigned flags)
    283 {
    284  TRACE_CALL(__func__);
    285  GtkWidget *grid;
    286  GtkWidget *password_entry;
    287  GtkWidget *username_entry;
    288  GtkWidget *domain_entry;
    289  GtkWidget *save_password_switch;
    290  GtkWidget *widget;
    291  GtkWidget *bbox;
    292  GtkWidget *button_ok;
    293  GtkWidget *button_cancel;
    294  int grid_row;
    295 
    296  RemminaMessagePanelPrivate *priv = remmina_message_panel_get_instance_private(mp);
    297 
    299  printf("WARNING: %s called in a subthread. This should not happen. Raising SIGINT to debug.\n", __func__);
    300  raise(SIGINT);
    301  }
    302 
    303  /* Create grid */
    304  grid = gtk_grid_new();
    305  gtk_widget_set_halign(GTK_WIDGET(grid), GTK_ALIGN_CENTER);
    306  gtk_widget_set_valign(GTK_WIDGET(grid), GTK_ALIGN_CENTER);
    307  gtk_widget_show(grid);
    308  gtk_grid_set_row_spacing(GTK_GRID(grid), 6);
    309  gtk_grid_set_column_spacing(GTK_GRID(grid), 6);
    310  //gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE);
    311 
    312  /* Entries */
    313 
    314  grid_row = 0;
    315  widget = gtk_label_new(title);
    316  gtk_style_context_add_class(gtk_widget_get_style_context(widget), "title_label");
    317  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    318  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_FILL);
    319  gtk_widget_set_margin_top (GTK_WIDGET(widget), 18);
    320  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 9);
    321  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    322  gtk_widget_set_margin_end (GTK_WIDGET(widget), 18);
    323  gtk_widget_show(widget);
    324  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 3, 1);
    325  grid_row++;
    326 
    327 
    329  widget = gtk_label_new(_("Username"));
    330  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    331  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER);
    332  gtk_widget_set_margin_top (GTK_WIDGET(widget), 9);
    333  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 3);
    334  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    335  gtk_widget_set_margin_end (GTK_WIDGET(widget), 6);
    336  gtk_widget_show(widget);
    337  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 1, 1);
    338 
    339  username_entry = gtk_entry_new();
    340  // gtk_style_context_add_class(gtk_widget_get_style_context(username_entry), "panel_entry");
    341  gtk_widget_set_halign(GTK_WIDGET(username_entry), GTK_ALIGN_FILL);
    342  gtk_widget_set_valign(GTK_WIDGET(username_entry), GTK_ALIGN_FILL);
    343  gtk_widget_set_margin_top (GTK_WIDGET(username_entry), 9);
    344  gtk_widget_set_margin_bottom (GTK_WIDGET(username_entry), 3);
    345  gtk_widget_set_margin_start (GTK_WIDGET(username_entry), 6);
    346  gtk_widget_set_margin_end (GTK_WIDGET(username_entry), 18);
    347  //gtk_entry_set_activates_default (GTK_ENTRY(username_entry), TRUE);
    348  gtk_grid_attach(GTK_GRID(grid), username_entry, 1, grid_row, 2, 1);
    349  gtk_entry_set_max_length(GTK_ENTRY(username_entry), 100);
    350 
    352  g_object_set(username_entry, "editable", FALSE, NULL);
    353  }
    354 
    355  /*
    356  if (default_username && default_username[0] != '\0') {
    357  gtk_entry_set_text(GTK_ENTRY(username_entry), default_username);
    358  }
    359  */
    360  grid_row++;
    361  } else {
    362  username_entry = NULL;
    363  }
    364 
    365  /* The password/key field */
    366  widget = gtk_label_new(password_prompt);
    367  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    368  gtk_widget_set_margin_top (GTK_WIDGET(widget), 3);
    369  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 3);
    370  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    371  gtk_widget_set_margin_end (GTK_WIDGET(widget), 6);
    372  gtk_widget_show(widget);
    373  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 1, 1);
    374 
    375  password_entry = gtk_entry_new();
    376  gtk_widget_set_halign(GTK_WIDGET(password_entry), GTK_ALIGN_FILL);
    377  gtk_widget_set_valign(GTK_WIDGET(password_entry), GTK_ALIGN_FILL);
    378  gtk_widget_set_margin_top (GTK_WIDGET(password_entry), 3);
    379  gtk_widget_set_margin_bottom (GTK_WIDGET(password_entry), 3);
    380  gtk_widget_set_margin_start (GTK_WIDGET(password_entry), 6);
    381  gtk_widget_set_margin_end (GTK_WIDGET(password_entry), 18);
    382  gtk_entry_set_activates_default (GTK_ENTRY(password_entry), TRUE);
    383  gtk_grid_attach(GTK_GRID(grid), password_entry, 1, grid_row, 2, 1);
    384  gtk_entry_set_max_length(GTK_ENTRY(password_entry), 0);
    385  gtk_entry_set_visibility(GTK_ENTRY(password_entry), FALSE);
    386 
    387  grid_row++;
    388 
    389  if (flags & REMMINA_MESSAGE_PANEL_FLAG_DOMAIN) {
    390  widget = gtk_label_new(_("Domain"));
    391  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    392  gtk_widget_set_margin_top (GTK_WIDGET(widget), 3);
    393  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 3);
    394  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    395  gtk_widget_set_margin_end (GTK_WIDGET(widget), 6);
    396  gtk_widget_show(widget);
    397  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 1, 1);
    398 
    399  domain_entry = gtk_entry_new();
    400  gtk_widget_set_halign(GTK_WIDGET(domain_entry), GTK_ALIGN_FILL);
    401  gtk_widget_set_valign(GTK_WIDGET(domain_entry), GTK_ALIGN_FILL);
    402  gtk_widget_set_margin_top (GTK_WIDGET(domain_entry), 3);
    403  gtk_widget_set_margin_bottom (GTK_WIDGET(domain_entry), 3);
    404  gtk_widget_set_margin_start (GTK_WIDGET(domain_entry), 6);
    405  gtk_widget_set_margin_end (GTK_WIDGET(domain_entry), 18);
    406  gtk_entry_set_activates_default (GTK_ENTRY(domain_entry), TRUE);
    407  gtk_widget_show(domain_entry);
    408  gtk_grid_attach(GTK_GRID(grid), domain_entry, 1, grid_row, 2, 1);
    409  gtk_entry_set_max_length(GTK_ENTRY(domain_entry), 100);
    410  /* if (default_domain && default_domain[0] != '\0') {
    411  gtk_entry_set_text(GTK_ENTRY(domain_entry), default_domain);
    412  } */
    413  grid_row ++;
    414  } else {
    415  domain_entry = NULL;
    416  }
    417 
    418 
    419  widget = gtk_label_new(_("Save password"));
    420  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    421  gtk_widget_set_margin_top (GTK_WIDGET(widget), 9);
    422  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 9);
    423  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    424  gtk_widget_set_margin_end (GTK_WIDGET(widget), 6);
    425  gtk_widget_show(widget);
    426  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 1, 1);
    427  save_password_switch = gtk_switch_new();
    428  gtk_widget_set_halign(GTK_WIDGET(save_password_switch), GTK_ALIGN_START);
    429  gtk_widget_set_valign(GTK_WIDGET(save_password_switch), GTK_ALIGN_FILL);
    430  gtk_widget_set_margin_top (GTK_WIDGET(save_password_switch), 9);
    431  gtk_widget_set_margin_bottom (GTK_WIDGET(save_password_switch), 9);
    432  gtk_widget_set_margin_start (GTK_WIDGET(save_password_switch), 6);
    433  gtk_widget_set_margin_end (GTK_WIDGET(save_password_switch), 18);
    434  gtk_grid_attach(GTK_GRID(grid), save_password_switch, 1, grid_row, 2, 1);
    436  gtk_switch_set_active(GTK_SWITCH(save_password_switch), TRUE);
    437  }else {
    438  gtk_switch_set_active(GTK_SWITCH(save_password_switch), FALSE);
    439  gtk_widget_set_sensitive(GTK_WIDGET(save_password_switch), FALSE);
    440  }
    441  grid_row ++;
    442 
    443  /* Buttons, ok and cancel */
    444  bbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
    445  gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_EDGE);
    446  gtk_box_set_spacing (GTK_BOX (bbox), 40);
    447  gtk_widget_set_margin_top (GTK_WIDGET(bbox), 9);
    448  gtk_widget_set_margin_bottom (GTK_WIDGET(bbox), 18);
    449  gtk_widget_set_margin_start (GTK_WIDGET(bbox), 18);
    450  gtk_widget_set_margin_end (GTK_WIDGET(bbox), 18);
    451  button_ok = gtk_button_new_with_label(_("_OK"));
    452  gtk_button_set_use_underline(GTK_BUTTON(button_ok), TRUE);
    453  gtk_widget_set_can_default(button_ok, TRUE);
    454  gtk_container_add (GTK_CONTAINER (bbox), button_ok);
    455  /* Buttons, ok and cancel */
    456  button_cancel = gtk_button_new_with_label(_("_Cancel"));
    457  gtk_button_set_use_underline(GTK_BUTTON(button_cancel), TRUE);
    458  gtk_container_add (GTK_CONTAINER (bbox), button_cancel);
    459  gtk_grid_attach(GTK_GRID(grid), bbox, 0, grid_row, 3, 1);
    460  /* Pack it into the panel */
    461  gtk_box_pack_start(GTK_BOX(mp), grid, TRUE, TRUE, 4);
    462 
    463  priv->w[REMMINA_MESSAGE_PANEL_USERNAME] = username_entry;
    464  priv->w[REMMINA_MESSAGE_PANEL_PASSWORD] = password_entry;
    465  priv->w[REMMINA_MESSAGE_PANEL_FLAG_SAVEPASSWORD] = save_password_switch;
    466  priv->w[REMMINA_MESSAGE_PANEL_DOMAIN] = domain_entry;
    467  priv->w[REMMINA_MESSAGE_PANEL_BUTTONTOFOCUS] = button_ok;
    468 
    469  priv->response_callback = response_callback;
    470  priv->response_callback_data = response_callback_data;
    471 
    472  if (username_entry) g_signal_connect_swapped (username_entry, "activate", (GCallback)gtk_widget_grab_focus, password_entry);
    473  g_signal_connect_swapped (password_entry, "activate", (GCallback)gtk_widget_grab_focus, button_ok);
    474  g_object_set_data(G_OBJECT(button_cancel), btn_response_key, (void *)GTK_RESPONSE_CANCEL);
    475  g_signal_connect(G_OBJECT(button_cancel), "clicked", G_CALLBACK(remmina_message_panel_button_clicked_callback), mp);
    476  g_object_set_data(G_OBJECT(button_ok), btn_response_key, (void *)GTK_RESPONSE_OK);
    477  g_signal_connect(G_OBJECT(button_ok), "clicked", G_CALLBACK(remmina_message_panel_button_clicked_callback), mp);
    478 }
    479 
    480 void remmina_message_panel_setup_auth_x509(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    481 {
    482  TRACE_CALL(__func__);
    483 
    484  GtkWidget *grid;
    485  GtkWidget *widget;
    486  GtkWidget *bbox;
    487  GtkWidget *button_ok;
    488  GtkWidget *button_cancel;
    489  GtkWidget *cacert_file;
    490  GtkWidget *cacrl_file;
    491  GtkWidget *clientcert_file;
    492  GtkWidget *clientkey_file;
    493  int grid_row;
    494 
    495  RemminaMessagePanelPrivate *priv = remmina_message_panel_get_instance_private(mp);
    496 
    498  printf("WARNING: %s called in a subthread. This should not happen. Raising SIGINT to debug.\n", __func__);
    499  raise(SIGINT);
    500  }
    501 
    502  /* Create grid */
    503  grid = gtk_grid_new();
    504  gtk_widget_set_halign(GTK_WIDGET(grid), GTK_ALIGN_CENTER);
    505  gtk_widget_set_valign(GTK_WIDGET(grid), GTK_ALIGN_CENTER);
    506  gtk_widget_show(grid);
    507  gtk_grid_set_row_spacing(GTK_GRID(grid), 6);
    508  gtk_grid_set_column_spacing(GTK_GRID(grid), 6);
    509 
    510  /* Entries */
    511  grid_row = 0;
    512  widget = gtk_label_new(_("Enter certificate authentication files"));
    513  gtk_style_context_add_class(gtk_widget_get_style_context(widget), "title_label");
    514  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    515  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_FILL);
    516  gtk_widget_set_margin_top (GTK_WIDGET(widget), 18);
    517  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 9);
    518  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    519  gtk_widget_set_margin_end (GTK_WIDGET(widget), 18);
    520  gtk_widget_show(widget);
    521  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 3, 1);
    522  grid_row++;
    523 
    524  const gchar *lbl_cacert = _("CA Certificate File");
    525  widget = gtk_label_new(lbl_cacert);
    526  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    527  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER);
    528  gtk_widget_set_margin_top (GTK_WIDGET(widget), 9);
    529  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 3);
    530  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    531  gtk_widget_set_margin_end (GTK_WIDGET(widget), 6);
    532  gtk_widget_show(widget);
    533  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 1, 1);
    534  cacert_file = gtk_file_chooser_button_new(lbl_cacert, GTK_FILE_CHOOSER_ACTION_OPEN);
    535  // gtk_style_context_add_class(gtk_widget_get_style_context(username_entry), "panel_entry");
    536  gtk_widget_show(cacert_file);
    537  gtk_widget_set_halign(GTK_WIDGET(cacert_file), GTK_ALIGN_FILL);
    538  gtk_widget_set_valign(GTK_WIDGET(cacert_file), GTK_ALIGN_FILL);
    539  gtk_widget_set_margin_top (GTK_WIDGET(cacert_file), 9);
    540  gtk_widget_set_margin_bottom (GTK_WIDGET(cacert_file), 3);
    541  gtk_widget_set_margin_start (GTK_WIDGET(cacert_file), 6);
    542  gtk_widget_set_margin_end (GTK_WIDGET(cacert_file), 18);
    543  gtk_grid_attach(GTK_GRID(grid), cacert_file, 1, grid_row, 2, 1);
    544  grid_row++;
    545 
    546  const gchar *lbl_cacrl = _("CA CRL File");
    547  widget = gtk_label_new(lbl_cacrl);
    548  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    549  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER);
    550  gtk_widget_set_margin_top (GTK_WIDGET(widget), 9);
    551  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 3);
    552  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    553  gtk_widget_set_margin_end (GTK_WIDGET(widget), 6);
    554  gtk_widget_show(widget);
    555  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 1, 1);
    556  cacrl_file = gtk_file_chooser_button_new(lbl_cacrl, GTK_FILE_CHOOSER_ACTION_OPEN);
    557  // gtk_style_context_add_class(gtk_widget_get_style_context(username_entry), "panel_entry");
    558  gtk_widget_show(cacrl_file);
    559  gtk_widget_set_halign(GTK_WIDGET(cacrl_file), GTK_ALIGN_FILL);
    560  gtk_widget_set_valign(GTK_WIDGET(cacrl_file), GTK_ALIGN_FILL);
    561  gtk_widget_set_margin_top (GTK_WIDGET(cacrl_file), 9);
    562  gtk_widget_set_margin_bottom (GTK_WIDGET(cacrl_file), 3);
    563  gtk_widget_set_margin_start (GTK_WIDGET(cacrl_file), 6);
    564  gtk_widget_set_margin_end (GTK_WIDGET(cacrl_file), 18);
    565  gtk_grid_attach(GTK_GRID(grid), cacrl_file, 1, grid_row, 2, 1);
    566  grid_row++;
    567 
    568  const gchar *lbl_clicert = _("Client Certificate File");
    569  widget = gtk_label_new(lbl_clicert);
    570  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    571  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER);
    572  gtk_widget_set_margin_top (GTK_WIDGET(widget), 9);
    573  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 3);
    574  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    575  gtk_widget_set_margin_end (GTK_WIDGET(widget), 6);
    576  gtk_widget_show(widget);
    577  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 1, 1);
    578  clientcert_file = gtk_file_chooser_button_new(lbl_clicert, GTK_FILE_CHOOSER_ACTION_OPEN);
    579  // gtk_style_context_add_class(gtk_widget_get_style_context(username_entry), "panel_entry");
    580  gtk_widget_show(clientcert_file);
    581  gtk_widget_set_halign(GTK_WIDGET(clientcert_file), GTK_ALIGN_FILL);
    582  gtk_widget_set_valign(GTK_WIDGET(clientcert_file), GTK_ALIGN_FILL);
    583  gtk_widget_set_margin_top (GTK_WIDGET(clientcert_file), 9);
    584  gtk_widget_set_margin_bottom (GTK_WIDGET(clientcert_file), 3);
    585  gtk_widget_set_margin_start (GTK_WIDGET(clientcert_file), 6);
    586  gtk_widget_set_margin_end (GTK_WIDGET(clientcert_file), 18);
    587  gtk_grid_attach(GTK_GRID(grid), clientcert_file, 1, grid_row, 2, 1);
    588  grid_row++;
    589 
    590  const gchar *lbl_clikey = _("Client Certificate Key");
    591  widget = gtk_label_new(lbl_clikey);
    592  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    593  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER);
    594  gtk_widget_set_margin_top (GTK_WIDGET(widget), 9);
    595  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 3);
    596  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    597  gtk_widget_set_margin_end (GTK_WIDGET(widget), 6);
    598  gtk_widget_show(widget);
    599  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 1, 1);
    600  clientkey_file = gtk_file_chooser_button_new(lbl_clikey, GTK_FILE_CHOOSER_ACTION_OPEN);
    601  // gtk_style_context_add_class(gtk_widget_get_style_context(username_entry), "panel_entry");
    602  gtk_widget_show(clientkey_file);
    603  gtk_widget_set_halign(GTK_WIDGET(clientkey_file), GTK_ALIGN_FILL);
    604  gtk_widget_set_valign(GTK_WIDGET(clientkey_file), GTK_ALIGN_FILL);
    605  gtk_widget_set_margin_top (GTK_WIDGET(clientkey_file), 9);
    606  gtk_widget_set_margin_bottom (GTK_WIDGET(clientkey_file), 3);
    607  gtk_widget_set_margin_start (GTK_WIDGET(clientkey_file), 6);
    608  gtk_widget_set_margin_end (GTK_WIDGET(clientkey_file), 18);
    609  gtk_grid_attach(GTK_GRID(grid), clientkey_file, 1, grid_row, 2, 1);
    610  grid_row++;
    611 
    612  /* Buttons, ok and cancel */
    613  bbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
    614  gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_EDGE);
    615  gtk_box_set_spacing (GTK_BOX (bbox), 40);
    616  gtk_widget_set_margin_top (GTK_WIDGET(bbox), 9);
    617  gtk_widget_set_margin_bottom (GTK_WIDGET(bbox), 18);
    618  gtk_widget_set_margin_start (GTK_WIDGET(bbox), 18);
    619  gtk_widget_set_margin_end (GTK_WIDGET(bbox), 18);
    620  button_ok = gtk_button_new_with_label(_("_OK"));
    621  gtk_widget_set_can_default (button_ok, TRUE);
    622 
    623  gtk_button_set_use_underline(GTK_BUTTON(button_ok), TRUE);
    624  //gtk_widget_show(button_ok);
    625  gtk_container_add (GTK_CONTAINER (bbox), button_ok);
    626  //gtk_grid_attach(GTK_GRID(grid), button_ok, 0, grid_row, 1, 1);
    627  /* Buttons, ok and cancel */
    628  button_cancel = gtk_button_new_with_label(_("_Cancel"));
    629  gtk_button_set_use_underline(GTK_BUTTON(button_cancel), TRUE);
    630  //gtk_widget_show(button_cancel);
    631  gtk_container_add (GTK_CONTAINER (bbox), button_cancel);
    632  gtk_grid_attach(GTK_GRID(grid), bbox, 0, grid_row, 3, 1);
    633  /* Pack it into the panel */
    634  gtk_box_pack_start(GTK_BOX(mp), grid, TRUE, TRUE, 4);
    635 
    636  priv->response_callback = response_callback;
    637  priv->response_callback_data = response_callback_data;
    638 
    639  priv->w[REMMINA_MESSAGE_PANEL_CACERTFILE] = cacert_file;
    640  priv->w[REMMINA_MESSAGE_PANEL_CACRLFILE] = cacrl_file;
    641  priv->w[REMMINA_MESSAGE_PANEL_CLIENTCERTFILE] = clientcert_file;
    642  priv->w[REMMINA_MESSAGE_PANEL_CLIENTKEYFILE] = clientkey_file;
    643  priv->w[REMMINA_MESSAGE_PANEL_BUTTONTOFOCUS] = button_ok;
    644 
    645  g_object_set_data(G_OBJECT(button_cancel), btn_response_key, (void *)GTK_RESPONSE_CANCEL);
    646  g_signal_connect(G_OBJECT(button_cancel), "clicked", G_CALLBACK(remmina_message_panel_button_clicked_callback), mp);
    647  g_object_set_data(G_OBJECT(button_ok), btn_response_key, (void *)GTK_RESPONSE_OK);
    648  g_signal_connect(G_OBJECT(button_ok), "clicked", G_CALLBACK(remmina_message_panel_button_clicked_callback), mp);
    649 
    650 }
    651 
    652 void remmina_message_panel_focus_auth_entry(RemminaMessagePanel *mp)
    653 {
    654  TRACE_CALL(__func__);
    655 
    657  GtkWidget *w;
    658  const gchar *username;
    659 
    660  if (mp == NULL)
    661  return;
    662  priv = remmina_message_panel_get_instance_private(mp);
    663 
    664  /* Activate default button */
    666  if (w && G_TYPE_CHECK_INSTANCE_TYPE(w, gtk_button_get_type()))
    667  gtk_widget_grab_default(w);
    668 
    670  if (w == NULL)
    671  {
    673  }else {
    674  username = gtk_entry_get_text(GTK_ENTRY(w));
    675  if (username[0] != 0)
    677  }
    678  if (w == NULL)
    679  return;
    680 
    681  if (!G_TYPE_CHECK_INSTANCE_TYPE(w, gtk_entry_get_type()))
    682  return;
    683 
    684  gtk_widget_grab_focus(w);
    685 }
    686 
    687 void remmina_message_panel_field_set_string(RemminaMessagePanel *mp, int entryid, const gchar *text)
    688 {
    690 
    691  if (mp == NULL)
    692  return;
    693  priv = remmina_message_panel_get_instance_private(mp);
    694 
    695  if (priv->w[entryid] == NULL)
    696  return;
    697  if (!G_TYPE_CHECK_INSTANCE_TYPE(priv->w[entryid], gtk_entry_get_type()))
    698  return;
    699 
    700  gtk_entry_set_text(GTK_ENTRY(priv->w[entryid]), text != NULL ? text : "");
    701 }
    702 
    703 gchar* remmina_message_panel_field_get_string(RemminaMessagePanel *mp, int entryid)
    704 {
    705  TRACE_CALL(__func__);
    706 
    708 
    709  if (mp == NULL)
    710  return NULL;
    711  priv = remmina_message_panel_get_instance_private(mp);
    712 
    713  if (priv->w[entryid] == NULL)
    714  return NULL;
    715  if (!G_TYPE_CHECK_INSTANCE_TYPE(priv->w[entryid], gtk_entry_get_type()))
    716  return NULL;
    717 
    718  return g_strdup(gtk_entry_get_text(GTK_ENTRY(priv->w[entryid])));
    719 }
    720 
    721 void remmina_message_panel_field_set_switch(RemminaMessagePanel *mp, int entryid, gboolean state)
    722 {
    723  TRACE_CALL(__func__);
    724 
    726 
    727  if (mp == NULL)
    728  return;
    729  priv = remmina_message_panel_get_instance_private(mp);
    730 
    731  if (priv->w[entryid] == NULL)
    732  return;
    733  if (!G_TYPE_CHECK_INSTANCE_TYPE(priv->w[entryid], gtk_switch_get_type()))
    734  return;
    735 
    736  gtk_switch_set_state(GTK_SWITCH(priv->w[entryid]), state);
    737 }
    738 
    739 gboolean remmina_message_panel_field_get_switch_state(RemminaMessagePanel *mp, int entryid)
    740 {
    741  TRACE_CALL(__func__);
    742 
    744 
    745  if (mp == NULL)
    746  return FALSE;
    747  priv = remmina_message_panel_get_instance_private(mp);
    748 
    749  if (priv->w[entryid] == NULL)
    750  return FALSE;
    751  if (!G_TYPE_CHECK_INSTANCE_TYPE(priv->w[entryid], gtk_switch_get_type()))
    752  return FALSE;
    753 
    754  return gtk_switch_get_state(GTK_SWITCH(priv->w[entryid]));
    755 }
    756 
    757 
    758 void remmina_message_panel_field_set_filename(RemminaMessagePanel *mp, int entryid, const gchar *filename)
    759 {
    760  TRACE_CALL(__func__);
    761 
    763 
    764  if (mp == NULL)
    765  return;
    766  priv = remmina_message_panel_get_instance_private(mp);
    767  if (priv->w[entryid] == NULL)
    768  return;
    769  if (!G_TYPE_CHECK_INSTANCE_TYPE(priv->w[entryid], gtk_file_chooser_button_get_type()))
    770  return;
    771 
    772  gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(priv->w[entryid]), filename);
    773 }
    774 
    775 gchar* remmina_message_panel_field_get_filename(RemminaMessagePanel *mp, int entryid)
    776 {
    777  TRACE_CALL(__func__);
    778 
    780 
    781  if (mp == NULL)
    782  return NULL;
    783  priv = remmina_message_panel_get_instance_private(mp);
    784 
    785  if (priv->w[entryid] == NULL)
    786  return NULL;
    787  if (!G_TYPE_CHECK_INSTANCE_TYPE(priv->w[entryid], gtk_file_chooser_button_get_type()))
    788  return NULL;
    789 
    790  return gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(priv->w[entryid]));
    791 }
    792 
    793 void remmina_message_panel_response(RemminaMessagePanel *mp, gint response_id)
    794 {
    795  g_signal_emit(mp, messagepanel_signals[RESPONSE], 0, response_id);
    796 }
    797 
    static void remmina_message_panel_init(RemminaMessagePanel *mp)
    -
    static guint messagepanel_signals[LAST_SIGNAL]
    +Go to the documentation of this file.
    1 /*
    2  * Remmina - The GTK+ Remote Desktop Client
    3  * Copyright (C) 2009-2011 Vic Lee
    4  * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
    5  * Copyright (C) 2016-2023 Antenore Gatta, Giovanni Panozzo
    6  *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    15  * GNU General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
    20  * Boston, MA 02110-1301, USA.
    21  *
    22  * In addition, as a special exception, the copyright holders give
    23  * permission to link the code of portions of this program with the
    24  * OpenSSL library under certain conditions as described in each
    25  * individual source file, and distribute linked combinations
    26  * including the two.
    27  * You must obey the GNU General Public License in all respects
    28  * for all of the code used other than OpenSSL. * If you modify
    29  * file(s) with this exception, you may extend this exception to your
    30  * version of the file(s), but you are not obligated to do so. * If you
    31  * do not wish to do so, delete this exception statement from your
    32  * version. * If you delete this exception statement from all source
    33  * files in the program, then also delete it here.
    34  *
    35  */
    36 
    37 #include <glib/gi18n.h>
    38 #include "config.h"
    39 #include "remmina_public.h"
    40 #include "remmina_widget_pool.h"
    41 #include "remmina_main.h"
    42 #include "remmina_message_panel.h"
    45 
    46 
    47 typedef struct
    48 {
    49 
    53 
    55 G_DEFINE_TYPE_WITH_PRIVATE (RemminaMessagePanel, remmina_message_panel, GTK_TYPE_BOX)
    56 
    57 
    58 enum {
    59  RESPONSE,
    61 };
    62 
    63 static guint messagepanel_signals[LAST_SIGNAL];
    64 
    65 static const gchar btn_response_key[] = "btn_response";
    66 
    67 static void remmina_message_panel_init (RemminaMessagePanel *mp)
    68 {
    69  TRACE_CALL(__func__);
    70 }
    71 
    72 static void remmina_message_panel_class_init(RemminaMessagePanelClass *class)
    73 {
    74  TRACE_CALL(__func__);
    75  // class->transform_text = my_app_label_real_transform_text;
    76 
    77  messagepanel_signals[RESPONSE] =
    78  g_signal_new ("response",
    79  G_OBJECT_CLASS_TYPE (class),
    80  G_SIGNAL_RUN_LAST,
    81  G_STRUCT_OFFSET (RemminaMessagePanelClass, response),
    82  NULL, NULL,
    83  NULL,
    84  G_TYPE_NONE, 1,
    85  G_TYPE_INT);
    86 }
    87 
    88 RemminaMessagePanel *remmina_message_panel_new()
    89 {
    90  TRACE_CALL(__func__);
    92  RemminaMessagePanel* mp;
    93  mp = (RemminaMessagePanel*)g_object_new(REMMINA_TYPE_MESSAGE_PANEL,
    94  "orientation", GTK_ORIENTATION_VERTICAL,
    95  "spacing", 0,
    96  NULL);
    97 
    98  priv = remmina_message_panel_get_instance_private(mp);
    99 
    100  priv->response_callback = NULL;
    101  priv->response_callback_data = NULL;
    102 
    103  /* Set widget class, for CSS styling */
    104  // gtk_widget_set_name(GTK_WIDGET(mp), "remmina-cw-message-panel");
    105  gtk_style_context_add_class(gtk_widget_get_style_context(GTK_WIDGET(mp)), "message_panel");
    106  gtk_style_context_add_class(gtk_widget_get_style_context(GTK_WIDGET(mp)), "background");
    107 
    108  return mp;
    109 }
    110 
    112  GtkButton *button, gpointer user_data)
    113 {
    114  TRACE_CALL(__func__);
    115  RemminaMessagePanel *mp = (RemminaMessagePanel*)user_data;
    116  RemminaMessagePanelPrivate *priv = remmina_message_panel_get_instance_private(mp);
    117 
    118  gint btn_data;
    119 
    120  btn_data = (gint)((gint64)g_object_get_data(G_OBJECT(button), btn_response_key));
    121 
    122  /* Calls the callback, if defined */
    123  if (priv->response_callback != NULL)
    124  (*priv->response_callback)(priv->response_callback_data, btn_data);
    125 
    126 }
    127 
    128 void remmina_message_panel_setup_progress(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    129 {
    130  /*
    131  * Setup a message panel to show a spinner, a message like "Connecting…",
    132  * and a button to cancel the action in progress
    133  *
    134  */
    135 
    136  TRACE_CALL(__func__);
    137  GtkBox *hbox;
    138  GtkWidget *w;
    139  RemminaMessagePanelPrivate *priv = remmina_message_panel_get_instance_private(mp);
    140 
    142  printf("WARNING: %s called in a subthread. This should not happen.\n", __func__);
    143  raise(SIGINT);
    144  }
    145 
    146  hbox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0));
    147 
    148  /* A spinner */
    149  w = gtk_spinner_new();
    150  gtk_box_pack_start(hbox, w, FALSE, FALSE, 0);
    151  gtk_spinner_start(GTK_SPINNER(w));
    152 
    153  /* A message */
    154  w = gtk_label_new(message);
    155  gtk_box_pack_start(hbox, w, TRUE, TRUE, 0);
    156 
    157  priv->response_callback = response_callback;
    158  priv->response_callback_data = response_callback_data;
    159 
    160  /* A button to cancel the action. The cancel button is available
    161  * only when a response_callback function is defined. */
    162  if (response_callback) {
    163  w = gtk_button_new_with_label(_("Cancel"));
    164  gtk_box_pack_end(hbox, w, FALSE, FALSE, 0);
    165  g_object_set_data(G_OBJECT(w), btn_response_key, (void *)GTK_RESPONSE_CANCEL);
    166  g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(remmina_message_panel_button_clicked_callback), mp);
    167  }
    168 
    169  gtk_box_pack_start(GTK_BOX(mp), GTK_WIDGET(hbox), TRUE, TRUE, 0);
    170 
    171  gtk_widget_show_all(GTK_WIDGET(mp));
    172 
    173 }
    174 
    175 void remmina_message_panel_setup_message(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    176 {
    177  /*
    178  * Setup a message panel to a message to read like "Cannot connect…",
    179  * and a button to close the panel
    180  *
    181  */
    182 
    183  TRACE_CALL(__func__);
    184  GtkBox *hbox;
    185  GtkWidget *w;
    186  RemminaMessagePanelPrivate *priv = remmina_message_panel_get_instance_private(mp);
    187 
    189  printf("WARNING: %s called in a subthread. This should not happen.\n", __func__);
    190  }
    191 
    192  hbox = GTK_BOX(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0));
    193 
    194  /* A message */
    195  w = gtk_label_new(message);
    196  gtk_box_pack_start(hbox, w, TRUE, TRUE, 0);
    197 
    198  /* A button to confirm reading */
    199  w = gtk_button_new_with_label(_("Close"));
    200  gtk_box_pack_end(hbox, w, FALSE, FALSE, 0);
    201 
    202  priv->response_callback = response_callback;
    203  priv->response_callback_data = response_callback_data;
    204 
    205  g_object_set_data(G_OBJECT(w), btn_response_key, (void *)GTK_RESPONSE_OK);
    206  g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(remmina_message_panel_button_clicked_callback), mp);
    207 
    208  gtk_box_pack_start(GTK_BOX(mp), GTK_WIDGET(hbox), TRUE, TRUE, 0);
    209 
    210  gtk_widget_show_all(GTK_WIDGET(mp));
    211 
    212 }
    213 
    214 void remmina_message_panel_setup_question(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    215 {
    216  /*
    217  * Setup a message panel to a message to read like "Do you accept ?",
    218  * and a pair of button for Yes and No
    219  * message is an HTML string
    220  * Callback will receive GTK_RESPONSE_NO for No, GTK_RESPONSE_YES for Yes
    221  *
    222  */
    223 
    224  TRACE_CALL(__func__);
    225  GtkWidget *grid;
    226  GtkWidget *bbox;
    227  GtkWidget *w;
    228  RemminaMessagePanelPrivate *priv = remmina_message_panel_get_instance_private(mp);
    229 
    231  printf("WARNING: %s called in a subthread. This should not happen. Raising SIGINT for debugging.\n", __func__);
    232  raise(SIGINT);
    233  }
    234 
    235  /* Create grid */
    236  grid = gtk_grid_new();
    237  gtk_widget_set_halign(GTK_WIDGET(grid), GTK_ALIGN_CENTER);
    238  gtk_widget_set_valign(GTK_WIDGET(grid), GTK_ALIGN_CENTER);
    239  gtk_widget_show(grid);
    240  gtk_grid_set_row_spacing(GTK_GRID(grid), 6);
    241  gtk_grid_set_column_spacing(GTK_GRID(grid), 6);
    242 
    243  /* A message, in HTML format */
    244  w = gtk_label_new(NULL);
    245  gtk_label_set_markup(GTK_LABEL(w), message);
    246 
    247  gtk_widget_set_halign(GTK_WIDGET(w), GTK_ALIGN_START);
    248  gtk_widget_set_valign(GTK_WIDGET(w), GTK_ALIGN_FILL);
    249  gtk_widget_set_margin_top (GTK_WIDGET(w), 18);
    250  gtk_widget_set_margin_bottom (GTK_WIDGET(w), 9);
    251  gtk_widget_set_margin_start (GTK_WIDGET(w), 18);
    252  gtk_widget_set_margin_end (GTK_WIDGET(w), 18);
    253  gtk_widget_show(w);
    254  gtk_grid_attach(GTK_GRID(grid), w, 0, 0, 2, 1);
    255 
    256  /* A button for yes and one for no */
    257  bbox = gtk_button_box_new (GTK_ORIENTATION_HORIZONTAL);
    258  gtk_button_box_set_layout(GTK_BUTTON_BOX(bbox), GTK_BUTTONBOX_START);
    259  gtk_grid_attach(GTK_GRID(grid), bbox, 0, 1, 1, 1);
    260  w = gtk_button_new_with_label(_("Yes"));
    261  gtk_widget_set_valign(GTK_WIDGET(w), GTK_ALIGN_CENTER);
    262  g_object_set_data(G_OBJECT(w), btn_response_key, (void *)GTK_RESPONSE_YES);
    263 
    264  g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(remmina_message_panel_button_clicked_callback), mp);
    265  gtk_container_add(GTK_CONTAINER(bbox), w);
    266 
    267  w = gtk_button_new_with_label(_("No"));
    268  gtk_widget_set_valign(GTK_WIDGET(w), GTK_ALIGN_CENTER);
    269  g_object_set_data(G_OBJECT(w), btn_response_key, (void *)GTK_RESPONSE_NO);
    270 
    271  priv->response_callback = response_callback;
    272  priv->response_callback_data = response_callback_data;
    273 
    274  g_signal_connect(G_OBJECT(w), "clicked", G_CALLBACK(remmina_message_panel_button_clicked_callback), mp);
    275  gtk_container_add(GTK_CONTAINER(bbox), w);
    276 
    277  gtk_box_pack_start(GTK_BOX(mp), GTK_WIDGET(grid), TRUE, TRUE, 0);
    278 
    279  gtk_widget_show_all(GTK_WIDGET(mp));
    280 
    281 }
    282 
    283 void remmina_message_panel_setup_auth(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data, const gchar *title, const gchar *password_prompt, unsigned flags)
    284 {
    285  TRACE_CALL(__func__);
    286  GtkWidget *grid;
    287  GtkWidget *password_entry;
    288  GtkWidget *username_entry;
    289  GtkWidget *domain_entry;
    290  GtkWidget *save_password_switch;
    291  GtkWidget *widget;
    292  GtkWidget *bbox;
    293  GtkWidget *button_ok;
    294  GtkWidget *button_cancel;
    295  int grid_row;
    296 
    297  RemminaMessagePanelPrivate *priv = remmina_message_panel_get_instance_private(mp);
    298 
    300  printf("WARNING: %s called in a subthread. This should not happen. Raising SIGINT to debug.\n", __func__);
    301  raise(SIGINT);
    302  }
    303 
    304  /* Create grid */
    305  grid = gtk_grid_new();
    306  gtk_widget_set_halign(GTK_WIDGET(grid), GTK_ALIGN_CENTER);
    307  gtk_widget_set_valign(GTK_WIDGET(grid), GTK_ALIGN_CENTER);
    308  gtk_widget_show(grid);
    309  gtk_grid_set_row_spacing(GTK_GRID(grid), 6);
    310  gtk_grid_set_column_spacing(GTK_GRID(grid), 6);
    311  //gtk_grid_set_column_homogeneous(GTK_GRID(grid), TRUE);
    312 
    313  /* Entries */
    314 
    315  grid_row = 0;
    316  widget = gtk_label_new(title);
    317  gtk_style_context_add_class(gtk_widget_get_style_context(widget), "title_label");
    318  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    319  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_FILL);
    320  gtk_widget_set_margin_top (GTK_WIDGET(widget), 18);
    321  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 9);
    322  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    323  gtk_widget_set_margin_end (GTK_WIDGET(widget), 18);
    324  gtk_widget_show(widget);
    325  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 3, 1);
    326  grid_row++;
    327 
    328 
    330  widget = gtk_label_new(_("Username"));
    331  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    332  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER);
    333  gtk_widget_set_margin_top (GTK_WIDGET(widget), 9);
    334  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 3);
    335  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    336  gtk_widget_set_margin_end (GTK_WIDGET(widget), 6);
    337  gtk_widget_show(widget);
    338  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 1, 1);
    339 
    340  username_entry = gtk_entry_new();
    341  // gtk_style_context_add_class(gtk_widget_get_style_context(username_entry), "panel_entry");
    342  gtk_widget_set_halign(GTK_WIDGET(username_entry), GTK_ALIGN_FILL);
    343  gtk_widget_set_valign(GTK_WIDGET(username_entry), GTK_ALIGN_FILL);
    344  gtk_widget_set_margin_top (GTK_WIDGET(username_entry), 9);
    345  gtk_widget_set_margin_bottom (GTK_WIDGET(username_entry), 3);
    346  gtk_widget_set_margin_start (GTK_WIDGET(username_entry), 6);
    347  gtk_widget_set_margin_end (GTK_WIDGET(username_entry), 18);
    348  //gtk_entry_set_activates_default (GTK_ENTRY(username_entry), TRUE);
    349  gtk_grid_attach(GTK_GRID(grid), username_entry, 1, grid_row, 2, 1);
    350  gtk_entry_set_max_length(GTK_ENTRY(username_entry), 100);
    351 
    353  g_object_set(username_entry, "editable", FALSE, NULL);
    354  }
    355 
    356  /*
    357  if (default_username && default_username[0] != '\0') {
    358  gtk_entry_set_text(GTK_ENTRY(username_entry), default_username);
    359  }
    360  */
    361  grid_row++;
    362  } else {
    363  username_entry = NULL;
    364  }
    365 
    366  /* The password/key field */
    367  widget = gtk_label_new(password_prompt);
    368  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    369  gtk_widget_set_margin_top (GTK_WIDGET(widget), 3);
    370  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 3);
    371  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    372  gtk_widget_set_margin_end (GTK_WIDGET(widget), 6);
    373  gtk_widget_show(widget);
    374  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 1, 1);
    375 
    376  password_entry = gtk_entry_new();
    377  gtk_widget_set_halign(GTK_WIDGET(password_entry), GTK_ALIGN_FILL);
    378  gtk_widget_set_valign(GTK_WIDGET(password_entry), GTK_ALIGN_FILL);
    379  gtk_widget_set_margin_top (GTK_WIDGET(password_entry), 3);
    380  gtk_widget_set_margin_bottom (GTK_WIDGET(password_entry), 3);
    381  gtk_widget_set_margin_start (GTK_WIDGET(password_entry), 6);
    382  gtk_widget_set_margin_end (GTK_WIDGET(password_entry), 18);
    383  gtk_entry_set_activates_default (GTK_ENTRY(password_entry), TRUE);
    384  gtk_grid_attach(GTK_GRID(grid), password_entry, 1, grid_row, 2, 1);
    385  gtk_entry_set_max_length(GTK_ENTRY(password_entry), 0);
    386  gtk_entry_set_visibility(GTK_ENTRY(password_entry), FALSE);
    387  gtk_entry_set_icon_from_icon_name(GTK_ENTRY(password_entry), GTK_ENTRY_ICON_SECONDARY, "org.remmina.Remmina-password-reveal-symbolic");
    388  gtk_entry_set_icon_activatable(GTK_ENTRY(password_entry), GTK_ENTRY_ICON_SECONDARY, TRUE);
    389  g_signal_connect(password_entry, "icon-press", G_CALLBACK(remmina_main_toggle_password_view), NULL);
    390 
    391  grid_row++;
    392 
    393  if (flags & REMMINA_MESSAGE_PANEL_FLAG_DOMAIN) {
    394  widget = gtk_label_new(_("Domain"));
    395  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    396  gtk_widget_set_margin_top (GTK_WIDGET(widget), 3);
    397  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 3);
    398  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    399  gtk_widget_set_margin_end (GTK_WIDGET(widget), 6);
    400  gtk_widget_show(widget);
    401  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 1, 1);
    402 
    403  domain_entry = gtk_entry_new();
    404  gtk_widget_set_halign(GTK_WIDGET(domain_entry), GTK_ALIGN_FILL);
    405  gtk_widget_set_valign(GTK_WIDGET(domain_entry), GTK_ALIGN_FILL);
    406  gtk_widget_set_margin_top (GTK_WIDGET(domain_entry), 3);
    407  gtk_widget_set_margin_bottom (GTK_WIDGET(domain_entry), 3);
    408  gtk_widget_set_margin_start (GTK_WIDGET(domain_entry), 6);
    409  gtk_widget_set_margin_end (GTK_WIDGET(domain_entry), 18);
    410  gtk_entry_set_activates_default (GTK_ENTRY(domain_entry), TRUE);
    411  gtk_widget_show(domain_entry);
    412  gtk_grid_attach(GTK_GRID(grid), domain_entry, 1, grid_row, 2, 1);
    413  gtk_entry_set_max_length(GTK_ENTRY(domain_entry), 100);
    414  /* if (default_domain && default_domain[0] != '\0') {
    415  gtk_entry_set_text(GTK_ENTRY(domain_entry), default_domain);
    416  } */
    417  grid_row ++;
    418  } else {
    419  domain_entry = NULL;
    420  }
    421 
    422 
    423  widget = gtk_label_new(_("Save password"));
    424  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    425  gtk_widget_set_margin_top (GTK_WIDGET(widget), 9);
    426  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 9);
    427  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    428  gtk_widget_set_margin_end (GTK_WIDGET(widget), 6);
    429  gtk_widget_show(widget);
    430  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 1, 1);
    431  save_password_switch = gtk_switch_new();
    432  gtk_widget_set_halign(GTK_WIDGET(save_password_switch), GTK_ALIGN_START);
    433  gtk_widget_set_valign(GTK_WIDGET(save_password_switch), GTK_ALIGN_FILL);
    434  gtk_widget_set_margin_top (GTK_WIDGET(save_password_switch), 9);
    435  gtk_widget_set_margin_bottom (GTK_WIDGET(save_password_switch), 9);
    436  gtk_widget_set_margin_start (GTK_WIDGET(save_password_switch), 6);
    437  gtk_widget_set_margin_end (GTK_WIDGET(save_password_switch), 18);
    438  gtk_grid_attach(GTK_GRID(grid), save_password_switch, 1, grid_row, 2, 1);
    440  gtk_switch_set_active(GTK_SWITCH(save_password_switch), TRUE);
    441  }else {
    442  gtk_switch_set_active(GTK_SWITCH(save_password_switch), FALSE);
    443  gtk_widget_set_sensitive(GTK_WIDGET(save_password_switch), FALSE);
    444  }
    445  grid_row ++;
    446 
    447  /* Buttons, ok and cancel */
    448  bbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
    449  gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_EDGE);
    450  gtk_box_set_spacing (GTK_BOX (bbox), 40);
    451  gtk_widget_set_margin_top (GTK_WIDGET(bbox), 9);
    452  gtk_widget_set_margin_bottom (GTK_WIDGET(bbox), 18);
    453  gtk_widget_set_margin_start (GTK_WIDGET(bbox), 18);
    454  gtk_widget_set_margin_end (GTK_WIDGET(bbox), 18);
    455  button_ok = gtk_button_new_with_label(_("_OK"));
    456  gtk_button_set_use_underline(GTK_BUTTON(button_ok), TRUE);
    457  gtk_widget_set_can_default(button_ok, TRUE);
    458  gtk_container_add (GTK_CONTAINER (bbox), button_ok);
    459  /* Buttons, ok and cancel */
    460  button_cancel = gtk_button_new_with_label(_("_Cancel"));
    461  gtk_button_set_use_underline(GTK_BUTTON(button_cancel), TRUE);
    462  gtk_container_add (GTK_CONTAINER (bbox), button_cancel);
    463  gtk_grid_attach(GTK_GRID(grid), bbox, 0, grid_row, 3, 1);
    464  /* Pack it into the panel */
    465  gtk_box_pack_start(GTK_BOX(mp), grid, TRUE, TRUE, 4);
    466 
    467  priv->w[REMMINA_MESSAGE_PANEL_USERNAME] = username_entry;
    468  priv->w[REMMINA_MESSAGE_PANEL_PASSWORD] = password_entry;
    469  priv->w[REMMINA_MESSAGE_PANEL_FLAG_SAVEPASSWORD] = save_password_switch;
    470  priv->w[REMMINA_MESSAGE_PANEL_DOMAIN] = domain_entry;
    471  priv->w[REMMINA_MESSAGE_PANEL_BUTTONTOFOCUS] = button_ok;
    472 
    473  priv->response_callback = response_callback;
    474  priv->response_callback_data = response_callback_data;
    475 
    476  if (username_entry) g_signal_connect_swapped (username_entry, "activate", (GCallback)gtk_widget_grab_focus, password_entry);
    477  g_signal_connect_swapped (password_entry, "activate", (GCallback)gtk_widget_grab_focus, button_ok);
    478  g_object_set_data(G_OBJECT(button_cancel), btn_response_key, (void *)GTK_RESPONSE_CANCEL);
    479  g_signal_connect(G_OBJECT(button_cancel), "clicked", G_CALLBACK(remmina_message_panel_button_clicked_callback), mp);
    480  g_object_set_data(G_OBJECT(button_ok), btn_response_key, (void *)GTK_RESPONSE_OK);
    481  g_signal_connect(G_OBJECT(button_ok), "clicked", G_CALLBACK(remmina_message_panel_button_clicked_callback), mp);
    482 }
    483 
    484 void remmina_message_panel_setup_auth_x509(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    485 {
    486  TRACE_CALL(__func__);
    487 
    488  GtkWidget *grid;
    489  GtkWidget *widget;
    490  GtkWidget *bbox;
    491  GtkWidget *button_ok;
    492  GtkWidget *button_cancel;
    493  GtkWidget *cacert_file;
    494  GtkWidget *cacrl_file;
    495  GtkWidget *clientcert_file;
    496  GtkWidget *clientkey_file;
    497  int grid_row;
    498 
    499  RemminaMessagePanelPrivate *priv = remmina_message_panel_get_instance_private(mp);
    500 
    502  printf("WARNING: %s called in a subthread. This should not happen. Raising SIGINT to debug.\n", __func__);
    503  raise(SIGINT);
    504  }
    505 
    506  /* Create grid */
    507  grid = gtk_grid_new();
    508  gtk_widget_set_halign(GTK_WIDGET(grid), GTK_ALIGN_CENTER);
    509  gtk_widget_set_valign(GTK_WIDGET(grid), GTK_ALIGN_CENTER);
    510  gtk_widget_show(grid);
    511  gtk_grid_set_row_spacing(GTK_GRID(grid), 6);
    512  gtk_grid_set_column_spacing(GTK_GRID(grid), 6);
    513 
    514  /* Entries */
    515  grid_row = 0;
    516  widget = gtk_label_new(_("Enter certificate authentication files"));
    517  gtk_style_context_add_class(gtk_widget_get_style_context(widget), "title_label");
    518  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    519  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_FILL);
    520  gtk_widget_set_margin_top (GTK_WIDGET(widget), 18);
    521  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 9);
    522  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    523  gtk_widget_set_margin_end (GTK_WIDGET(widget), 18);
    524  gtk_widget_show(widget);
    525  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 3, 1);
    526  grid_row++;
    527 
    528  const gchar *lbl_cacert = _("CA Certificate File");
    529  widget = gtk_label_new(lbl_cacert);
    530  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    531  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER);
    532  gtk_widget_set_margin_top (GTK_WIDGET(widget), 9);
    533  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 3);
    534  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    535  gtk_widget_set_margin_end (GTK_WIDGET(widget), 6);
    536  gtk_widget_show(widget);
    537  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 1, 1);
    538  cacert_file = gtk_file_chooser_button_new(lbl_cacert, GTK_FILE_CHOOSER_ACTION_OPEN);
    539  // gtk_style_context_add_class(gtk_widget_get_style_context(username_entry), "panel_entry");
    540  gtk_widget_show(cacert_file);
    541  gtk_widget_set_halign(GTK_WIDGET(cacert_file), GTK_ALIGN_FILL);
    542  gtk_widget_set_valign(GTK_WIDGET(cacert_file), GTK_ALIGN_FILL);
    543  gtk_widget_set_margin_top (GTK_WIDGET(cacert_file), 9);
    544  gtk_widget_set_margin_bottom (GTK_WIDGET(cacert_file), 3);
    545  gtk_widget_set_margin_start (GTK_WIDGET(cacert_file), 6);
    546  gtk_widget_set_margin_end (GTK_WIDGET(cacert_file), 18);
    547  gtk_grid_attach(GTK_GRID(grid), cacert_file, 1, grid_row, 2, 1);
    548  grid_row++;
    549 
    550  const gchar *lbl_cacrl = _("CA CRL File");
    551  widget = gtk_label_new(lbl_cacrl);
    552  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    553  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER);
    554  gtk_widget_set_margin_top (GTK_WIDGET(widget), 9);
    555  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 3);
    556  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    557  gtk_widget_set_margin_end (GTK_WIDGET(widget), 6);
    558  gtk_widget_show(widget);
    559  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 1, 1);
    560  cacrl_file = gtk_file_chooser_button_new(lbl_cacrl, GTK_FILE_CHOOSER_ACTION_OPEN);
    561  // gtk_style_context_add_class(gtk_widget_get_style_context(username_entry), "panel_entry");
    562  gtk_widget_show(cacrl_file);
    563  gtk_widget_set_halign(GTK_WIDGET(cacrl_file), GTK_ALIGN_FILL);
    564  gtk_widget_set_valign(GTK_WIDGET(cacrl_file), GTK_ALIGN_FILL);
    565  gtk_widget_set_margin_top (GTK_WIDGET(cacrl_file), 9);
    566  gtk_widget_set_margin_bottom (GTK_WIDGET(cacrl_file), 3);
    567  gtk_widget_set_margin_start (GTK_WIDGET(cacrl_file), 6);
    568  gtk_widget_set_margin_end (GTK_WIDGET(cacrl_file), 18);
    569  gtk_grid_attach(GTK_GRID(grid), cacrl_file, 1, grid_row, 2, 1);
    570  grid_row++;
    571 
    572  const gchar *lbl_clicert = _("Client Certificate File");
    573  widget = gtk_label_new(lbl_clicert);
    574  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    575  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER);
    576  gtk_widget_set_margin_top (GTK_WIDGET(widget), 9);
    577  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 3);
    578  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    579  gtk_widget_set_margin_end (GTK_WIDGET(widget), 6);
    580  gtk_widget_show(widget);
    581  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 1, 1);
    582  clientcert_file = gtk_file_chooser_button_new(lbl_clicert, GTK_FILE_CHOOSER_ACTION_OPEN);
    583  // gtk_style_context_add_class(gtk_widget_get_style_context(username_entry), "panel_entry");
    584  gtk_widget_show(clientcert_file);
    585  gtk_widget_set_halign(GTK_WIDGET(clientcert_file), GTK_ALIGN_FILL);
    586  gtk_widget_set_valign(GTK_WIDGET(clientcert_file), GTK_ALIGN_FILL);
    587  gtk_widget_set_margin_top (GTK_WIDGET(clientcert_file), 9);
    588  gtk_widget_set_margin_bottom (GTK_WIDGET(clientcert_file), 3);
    589  gtk_widget_set_margin_start (GTK_WIDGET(clientcert_file), 6);
    590  gtk_widget_set_margin_end (GTK_WIDGET(clientcert_file), 18);
    591  gtk_grid_attach(GTK_GRID(grid), clientcert_file, 1, grid_row, 2, 1);
    592  grid_row++;
    593 
    594  const gchar *lbl_clikey = _("Client Certificate Key");
    595  widget = gtk_label_new(lbl_clikey);
    596  gtk_widget_set_halign(GTK_WIDGET(widget), GTK_ALIGN_START);
    597  gtk_widget_set_valign(GTK_WIDGET(widget), GTK_ALIGN_CENTER);
    598  gtk_widget_set_margin_top (GTK_WIDGET(widget), 9);
    599  gtk_widget_set_margin_bottom (GTK_WIDGET(widget), 3);
    600  gtk_widget_set_margin_start (GTK_WIDGET(widget), 18);
    601  gtk_widget_set_margin_end (GTK_WIDGET(widget), 6);
    602  gtk_widget_show(widget);
    603  gtk_grid_attach(GTK_GRID(grid), widget, 0, grid_row, 1, 1);
    604  clientkey_file = gtk_file_chooser_button_new(lbl_clikey, GTK_FILE_CHOOSER_ACTION_OPEN);
    605  // gtk_style_context_add_class(gtk_widget_get_style_context(username_entry), "panel_entry");
    606  gtk_widget_show(clientkey_file);
    607  gtk_widget_set_halign(GTK_WIDGET(clientkey_file), GTK_ALIGN_FILL);
    608  gtk_widget_set_valign(GTK_WIDGET(clientkey_file), GTK_ALIGN_FILL);
    609  gtk_widget_set_margin_top (GTK_WIDGET(clientkey_file), 9);
    610  gtk_widget_set_margin_bottom (GTK_WIDGET(clientkey_file), 3);
    611  gtk_widget_set_margin_start (GTK_WIDGET(clientkey_file), 6);
    612  gtk_widget_set_margin_end (GTK_WIDGET(clientkey_file), 18);
    613  gtk_grid_attach(GTK_GRID(grid), clientkey_file, 1, grid_row, 2, 1);
    614  grid_row++;
    615 
    616  /* Buttons, ok and cancel */
    617  bbox = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
    618  gtk_button_box_set_layout (GTK_BUTTON_BOX (bbox), GTK_BUTTONBOX_EDGE);
    619  gtk_box_set_spacing (GTK_BOX (bbox), 40);
    620  gtk_widget_set_margin_top (GTK_WIDGET(bbox), 9);
    621  gtk_widget_set_margin_bottom (GTK_WIDGET(bbox), 18);
    622  gtk_widget_set_margin_start (GTK_WIDGET(bbox), 18);
    623  gtk_widget_set_margin_end (GTK_WIDGET(bbox), 18);
    624  button_ok = gtk_button_new_with_label(_("_OK"));
    625  gtk_widget_set_can_default (button_ok, TRUE);
    626 
    627  gtk_button_set_use_underline(GTK_BUTTON(button_ok), TRUE);
    628  //gtk_widget_show(button_ok);
    629  gtk_container_add (GTK_CONTAINER (bbox), button_ok);
    630  //gtk_grid_attach(GTK_GRID(grid), button_ok, 0, grid_row, 1, 1);
    631  /* Buttons, ok and cancel */
    632  button_cancel = gtk_button_new_with_label(_("_Cancel"));
    633  gtk_button_set_use_underline(GTK_BUTTON(button_cancel), TRUE);
    634  //gtk_widget_show(button_cancel);
    635  gtk_container_add (GTK_CONTAINER (bbox), button_cancel);
    636  gtk_grid_attach(GTK_GRID(grid), bbox, 0, grid_row, 3, 1);
    637  /* Pack it into the panel */
    638  gtk_box_pack_start(GTK_BOX(mp), grid, TRUE, TRUE, 4);
    639 
    640  priv->response_callback = response_callback;
    641  priv->response_callback_data = response_callback_data;
    642 
    643  priv->w[REMMINA_MESSAGE_PANEL_CACERTFILE] = cacert_file;
    644  priv->w[REMMINA_MESSAGE_PANEL_CACRLFILE] = cacrl_file;
    645  priv->w[REMMINA_MESSAGE_PANEL_CLIENTCERTFILE] = clientcert_file;
    646  priv->w[REMMINA_MESSAGE_PANEL_CLIENTKEYFILE] = clientkey_file;
    647  priv->w[REMMINA_MESSAGE_PANEL_BUTTONTOFOCUS] = button_ok;
    648 
    649  g_object_set_data(G_OBJECT(button_cancel), btn_response_key, (void *)GTK_RESPONSE_CANCEL);
    650  g_signal_connect(G_OBJECT(button_cancel), "clicked", G_CALLBACK(remmina_message_panel_button_clicked_callback), mp);
    651  g_object_set_data(G_OBJECT(button_ok), btn_response_key, (void *)GTK_RESPONSE_OK);
    652  g_signal_connect(G_OBJECT(button_ok), "clicked", G_CALLBACK(remmina_message_panel_button_clicked_callback), mp);
    653 
    654 }
    655 
    656 void remmina_message_panel_focus_auth_entry(RemminaMessagePanel *mp)
    657 {
    658  TRACE_CALL(__func__);
    659 
    661  GtkWidget *w;
    662  const gchar *username;
    663 
    664  if (mp == NULL)
    665  return;
    666  priv = remmina_message_panel_get_instance_private(mp);
    667 
    668  /* Activate default button */
    670  if (w && G_TYPE_CHECK_INSTANCE_TYPE(w, gtk_button_get_type()))
    671  gtk_widget_grab_default(w);
    672 
    674  if (w == NULL)
    675  {
    677  }else {
    678  username = gtk_entry_get_text(GTK_ENTRY(w));
    679  if (username[0] != 0)
    681  }
    682  if (w == NULL)
    683  return;
    684 
    685  if (!G_TYPE_CHECK_INSTANCE_TYPE(w, gtk_entry_get_type()))
    686  return;
    687 
    688  gtk_widget_grab_focus(w);
    689 }
    690 
    691 void remmina_message_panel_field_set_string(RemminaMessagePanel *mp, int entryid, const gchar *text)
    692 {
    694 
    695  if (mp == NULL)
    696  return;
    697  priv = remmina_message_panel_get_instance_private(mp);
    698 
    699  if (priv->w[entryid] == NULL)
    700  return;
    701  if (!G_TYPE_CHECK_INSTANCE_TYPE(priv->w[entryid], gtk_entry_get_type()))
    702  return;
    703 
    704  gtk_entry_set_text(GTK_ENTRY(priv->w[entryid]), text != NULL ? text : "");
    705 }
    706 
    707 gchar* remmina_message_panel_field_get_string(RemminaMessagePanel *mp, int entryid)
    708 {
    709  TRACE_CALL(__func__);
    710 
    712 
    713  if (mp == NULL)
    714  return NULL;
    715  priv = remmina_message_panel_get_instance_private(mp);
    716 
    717  if (priv->w[entryid] == NULL)
    718  return NULL;
    719  if (!G_TYPE_CHECK_INSTANCE_TYPE(priv->w[entryid], gtk_entry_get_type()))
    720  return NULL;
    721 
    722  return g_strdup(gtk_entry_get_text(GTK_ENTRY(priv->w[entryid])));
    723 }
    724 
    725 void remmina_message_panel_field_set_switch(RemminaMessagePanel *mp, int entryid, gboolean state)
    726 {
    727  TRACE_CALL(__func__);
    728 
    730 
    731  if (mp == NULL)
    732  return;
    733  priv = remmina_message_panel_get_instance_private(mp);
    734 
    735  if (priv->w[entryid] == NULL)
    736  return;
    737  if (!G_TYPE_CHECK_INSTANCE_TYPE(priv->w[entryid], gtk_switch_get_type()))
    738  return;
    739 
    740  gtk_switch_set_state(GTK_SWITCH(priv->w[entryid]), state);
    741 }
    742 
    743 gboolean remmina_message_panel_field_get_switch_state(RemminaMessagePanel *mp, int entryid)
    744 {
    745  TRACE_CALL(__func__);
    746 
    748 
    749  if (mp == NULL)
    750  return FALSE;
    751  priv = remmina_message_panel_get_instance_private(mp);
    752 
    753  if (priv->w[entryid] == NULL)
    754  return FALSE;
    755  if (!G_TYPE_CHECK_INSTANCE_TYPE(priv->w[entryid], gtk_switch_get_type()))
    756  return FALSE;
    757 
    758  return gtk_switch_get_state(GTK_SWITCH(priv->w[entryid]));
    759 }
    760 
    761 
    762 void remmina_message_panel_field_set_filename(RemminaMessagePanel *mp, int entryid, const gchar *filename)
    763 {
    764  TRACE_CALL(__func__);
    765 
    767 
    768  if (mp == NULL)
    769  return;
    770  priv = remmina_message_panel_get_instance_private(mp);
    771  if (priv->w[entryid] == NULL)
    772  return;
    773  if (!G_TYPE_CHECK_INSTANCE_TYPE(priv->w[entryid], gtk_file_chooser_button_get_type()))
    774  return;
    775 
    776  gtk_file_chooser_set_filename(GTK_FILE_CHOOSER(priv->w[entryid]), filename);
    777 }
    778 
    779 gchar* remmina_message_panel_field_get_filename(RemminaMessagePanel *mp, int entryid)
    780 {
    781  TRACE_CALL(__func__);
    782 
    784 
    785  if (mp == NULL)
    786  return NULL;
    787  priv = remmina_message_panel_get_instance_private(mp);
    788 
    789  if (priv->w[entryid] == NULL)
    790  return NULL;
    791  if (!G_TYPE_CHECK_INSTANCE_TYPE(priv->w[entryid], gtk_file_chooser_button_get_type()))
    792  return NULL;
    793 
    794  return gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(priv->w[entryid]));
    795 }
    796 
    797 void remmina_message_panel_response(RemminaMessagePanel *mp, gint response_id)
    798 {
    799  g_signal_emit(mp, messagepanel_signals[RESPONSE], 0, response_id);
    800 }
    801 
    static void remmina_message_panel_init(RemminaMessagePanel *mp)
    +
    static guint messagepanel_signals[LAST_SIGNAL]
    -
    void remmina_message_panel_setup_auth(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data, const gchar *title, const gchar *password_prompt, unsigned flags)
    +
    void remmina_message_panel_setup_auth(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data, const gchar *title, const gchar *password_prompt, unsigned flags)
    -
    void remmina_message_panel_setup_question(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    -
    gchar * remmina_message_panel_field_get_filename(RemminaMessagePanel *mp, int entryid)
    +
    void remmina_message_panel_setup_question(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    +
    gchar * remmina_message_panel_field_get_filename(RemminaMessagePanel *mp, int entryid)
    - -
    void remmina_message_panel_setup_auth_x509(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    -
    static void remmina_message_panel_class_init(RemminaMessagePanelClass *class)
    + +
    void remmina_message_panel_setup_auth_x509(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    +
    static void remmina_message_panel_class_init(RemminaMessagePanelClass *class)
    -
    void remmina_message_panel_focus_auth_entry(RemminaMessagePanel *mp)
    -
    void remmina_message_panel_field_set_string(RemminaMessagePanel *mp, int entryid, const gchar *text)
    +
    void remmina_message_panel_focus_auth_entry(RemminaMessagePanel *mp)
    +
    void remmina_message_panel_field_set_string(RemminaMessagePanel *mp, int entryid, const gchar *text)
    + -
    void remmina_message_panel_field_set_filename(RemminaMessagePanel *mp, int entryid, const gchar *filename)
    +
    void remmina_message_panel_field_set_filename(RemminaMessagePanel *mp, int entryid, const gchar *filename)
    gboolean remmina_masterthread_exec_is_main_thread()
    -
    void remmina_message_panel_field_set_switch(RemminaMessagePanel *mp, int entryid, gboolean state)
    +
    void remmina_message_panel_field_set_switch(RemminaMessagePanel *mp, int entryid, gboolean state)
    void(* RemminaMessagePanelCallback)(void *user_data, int button)
    -
    G_DEFINE_TYPE_WITH_PRIVATE(RemminaMessagePanel, remmina_message_panel, GTK_TYPE_BOX)
    -
    gchar * remmina_message_panel_field_get_string(RemminaMessagePanel *mp, int entryid)
    +
    G_DEFINE_TYPE_WITH_PRIVATE(RemminaMessagePanel, remmina_message_panel, GTK_TYPE_BOX)
    +
    gchar * remmina_message_panel_field_get_string(RemminaMessagePanel *mp, int entryid)
    -
    void remmina_message_panel_setup_progress(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    +
    void remmina_message_panel_setup_progress(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    - + -
    void remmina_message_panel_setup_message(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    -
    gboolean remmina_message_panel_field_get_switch_state(RemminaMessagePanel *mp, int entryid)
    -
    static const gchar btn_response_key[]
    +
    void remmina_main_toggle_password_view(GtkWidget *widget, gpointer data)
    +
    void remmina_message_panel_setup_message(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    +
    gboolean remmina_message_panel_field_get_switch_state(RemminaMessagePanel *mp, int entryid)
    +
    static const gchar btn_response_key[]
    -
    void remmina_message_panel_response(RemminaMessagePanel *mp, gint response_id)
    -
    RemminaMessagePanelCallback response_callback
    -
    GtkWidget * w[REMMINA_MESSAGE_PANEL_MAXWIDGETID]
    -
    RemminaMessagePanel * remmina_message_panel_new()
    -
    static void remmina_message_panel_button_clicked_callback(GtkButton *button, gpointer user_data)
    +
    void remmina_message_panel_response(RemminaMessagePanel *mp, gint response_id)
    +
    RemminaMessagePanelCallback response_callback
    +
    GtkWidget * w[REMMINA_MESSAGE_PANEL_MAXWIDGETID]
    +
    RemminaMessagePanel * remmina_message_panel_new()
    +
    static void remmina_message_panel_button_clicked_callback(GtkButton *button, gpointer user_data)
    diff --git a/public/remmina__message__panel_8h.html b/public/remmina__message__panel_8h.html index 702d7be0d..33906931e 100644 --- a/public/remmina__message__panel_8h.html +++ b/public/remmina__message__panel_8h.html @@ -271,7 +271,7 @@ Functions
    -

    Definition at line 775 of file remmina_message_panel.c.

    +

    Definition at line 779 of file remmina_message_panel.c.

    @@ -301,7 +301,7 @@ Functions
    -

    Definition at line 703 of file remmina_message_panel.c.

    +

    Definition at line 707 of file remmina_message_panel.c.

    @@ -331,7 +331,7 @@ Functions
    -

    Definition at line 739 of file remmina_message_panel.c.

    +

    Definition at line 743 of file remmina_message_panel.c.

    @@ -367,7 +367,7 @@ Functions
    -

    Definition at line 758 of file remmina_message_panel.c.

    +

    Definition at line 762 of file remmina_message_panel.c.

    @@ -403,7 +403,7 @@ Functions
    -

    Definition at line 687 of file remmina_message_panel.c.

    +

    Definition at line 691 of file remmina_message_panel.c.

    @@ -439,7 +439,7 @@ Functions
    -

    Definition at line 721 of file remmina_message_panel.c.

    +

    Definition at line 725 of file remmina_message_panel.c.

    @@ -459,7 +459,7 @@ Functions
    -

    Definition at line 652 of file remmina_message_panel.c.

    +

    Definition at line 656 of file remmina_message_panel.c.

    @@ -479,7 +479,7 @@ Functions
    -

    Definition at line 87 of file remmina_message_panel.c.

    +

    Definition at line 88 of file remmina_message_panel.c.

    @@ -509,7 +509,7 @@ Functions
    -

    Definition at line 793 of file remmina_message_panel.c.

    +

    Definition at line 797 of file remmina_message_panel.c.

    @@ -563,7 +563,7 @@ Functions
    -

    Definition at line 282 of file remmina_message_panel.c.

    +

    Definition at line 283 of file remmina_message_panel.c.

    @@ -599,7 +599,7 @@ Functions
    -

    Definition at line 480 of file remmina_message_panel.c.

    +

    Definition at line 484 of file remmina_message_panel.c.

    @@ -641,7 +641,7 @@ Functions
    -

    Definition at line 174 of file remmina_message_panel.c.

    +

    Definition at line 175 of file remmina_message_panel.c.

    @@ -683,7 +683,7 @@ Functions
    -

    Definition at line 127 of file remmina_message_panel.c.

    +

    Definition at line 128 of file remmina_message_panel.c.

    @@ -725,7 +725,7 @@ Functions
    -

    Definition at line 213 of file remmina_message_panel.c.

    +

    Definition at line 214 of file remmina_message_panel.c.

    diff --git a/public/remmina__message__panel_8h_source.html b/public/remmina__message__panel_8h_source.html index 21abd74b1..92ccaf508 100644 --- a/public/remmina__message__panel_8h_source.html +++ b/public/remmina__message__panel_8h_source.html @@ -86,29 +86,29 @@ $(document).ready(function(){initNavTree('remmina__message__panel_8h_source.html
    remmina_message_panel.h
    -Go to the documentation of this file.
    1 /*
    2  * Remmina - The GTK+ Remote Desktop Client
    3  * Copyright (C) 2009-2011 Vic Lee
    4  * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
    5  * Copyright (C) 2016-2023 Antenore Gatta, Giovanni Panozzo
    6  *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    15  * GNU General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
    20  * Boston, MA 02110-1301, USA.
    21  *
    22  * In addition, as a special exception, the copyright holders give
    23  * permission to link the code of portions of this program with the
    24  * OpenSSL library under certain conditions as described in each
    25  * individual source file, and distribute linked combinations
    26  * including the two.
    27  * You must obey the GNU General Public License in all respects
    28  * for all of the code used other than OpenSSL. * If you modify
    29  * file(s) with this exception, you may extend this exception to your
    30  * version of the file(s), but you are not obligated to do so. * If you
    31  * do not wish to do so, delete this exception statement from your
    32  * version. * If you delete this exception statement from all source
    33  * files in the program, then also delete it here.
    34  *
    35  */
    36 
    37 #pragma once
    38 
    39 #include <gtk/gtk.h>
    40 
    41 G_BEGIN_DECLS
    42 
    43 #define REMMINA_TYPE_MESSAGE_PANEL (remmina_message_panel_get_type())
    44 G_DECLARE_DERIVABLE_TYPE(RemminaMessagePanel, remmina_message_panel, REMMINA, MESSAGE_PANEL, GtkBox)
    45 
    46 struct _RemminaMessagePanelClass {
    47  GtkBoxClass parent_class;
    48  void (*response) (RemminaMessagePanel *mp, gint response_id);
    49 };
    50 
    51 
    52 /* Widgets ID for dialog fields */
    53 enum {
    64 };
    65 
    66 /* Callback function type to receive buttons notification */
    67 typedef void (*RemminaMessagePanelCallback)(void *user_data, int button);
    68 
    69 RemminaMessagePanel *remmina_message_panel_new(void);
    70 void remmina_message_panel_setup_progress(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data);
    71 void remmina_message_panel_setup_message(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data);
    72 void remmina_message_panel_setup_question(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data);
    73 void remmina_message_panel_setup_auth(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data, const gchar *title, const gchar *password_prompt, unsigned flags);
    74 void remmina_message_panel_setup_auth_x509(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data);
    75 void remmina_message_panel_focus_auth_entry(RemminaMessagePanel *mp);
    76 void remmina_message_panel_field_set_string(RemminaMessagePanel *mp, int entryid, const gchar *text);
    77 gchar *remmina_message_panel_field_get_string(RemminaMessagePanel *mp, int entryid);
    78 void remmina_message_panel_field_set_switch(RemminaMessagePanel *mp, int entryid, gboolean state);
    79 gboolean remmina_message_panel_field_get_switch_state(RemminaMessagePanel *mp, int entryid);
    80 void remmina_message_panel_field_set_filename(RemminaMessagePanel *mp, int entryid, const gchar *filename);
    81 gchar *remmina_message_panel_field_get_filename(RemminaMessagePanel *mp, int entryid);
    82 void remmina_message_panel_response(RemminaMessagePanel *mp, gint response_id);
    83 
    84 
    85 G_END_DECLS
    void remmina_message_panel_field_set_string(RemminaMessagePanel *mp, int entryid, const gchar *text)
    +Go to the documentation of this file.
    1 /*
    2  * Remmina - The GTK+ Remote Desktop Client
    3  * Copyright (C) 2009-2011 Vic Lee
    4  * Copyright (C) 2014-2015 Antenore Gatta, Fabio Castelli, Giovanni Panozzo
    5  * Copyright (C) 2016-2023 Antenore Gatta, Giovanni Panozzo
    6  *
    7  * This program is free software; you can redistribute it and/or modify
    8  * it under the terms of the GNU General Public License as published by
    9  * the Free Software Foundation; either version 2 of the License, or
    10  * (at your option) any later version.
    11  *
    12  * This program is distributed in the hope that it will be useful,
    13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    15  * GNU General Public License for more details.
    16  *
    17  * You should have received a copy of the GNU General Public License
    18  * along with this program; if not, write to the Free Software
    19  * Foundation, Inc., 51 Franklin Street, Fifth Floor,
    20  * Boston, MA 02110-1301, USA.
    21  *
    22  * In addition, as a special exception, the copyright holders give
    23  * permission to link the code of portions of this program with the
    24  * OpenSSL library under certain conditions as described in each
    25  * individual source file, and distribute linked combinations
    26  * including the two.
    27  * You must obey the GNU General Public License in all respects
    28  * for all of the code used other than OpenSSL. * If you modify
    29  * file(s) with this exception, you may extend this exception to your
    30  * version of the file(s), but you are not obligated to do so. * If you
    31  * do not wish to do so, delete this exception statement from your
    32  * version. * If you delete this exception statement from all source
    33  * files in the program, then also delete it here.
    34  *
    35  */
    36 
    37 #pragma once
    38 
    39 #include <gtk/gtk.h>
    40 
    41 G_BEGIN_DECLS
    42 
    43 #define REMMINA_TYPE_MESSAGE_PANEL (remmina_message_panel_get_type())
    44 G_DECLARE_DERIVABLE_TYPE(RemminaMessagePanel, remmina_message_panel, REMMINA, MESSAGE_PANEL, GtkBox)
    45 
    46 struct _RemminaMessagePanelClass {
    47  GtkBoxClass parent_class;
    48  void (*response) (RemminaMessagePanel *mp, gint response_id);
    49 };
    50 
    51 
    52 /* Widgets ID for dialog fields */
    53 enum {
    64 };
    65 
    66 /* Callback function type to receive buttons notification */
    67 typedef void (*RemminaMessagePanelCallback)(void *user_data, int button);
    68 
    69 RemminaMessagePanel *remmina_message_panel_new(void);
    70 void remmina_message_panel_setup_progress(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data);
    71 void remmina_message_panel_setup_message(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data);
    72 void remmina_message_panel_setup_question(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data);
    73 void remmina_message_panel_setup_auth(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data, const gchar *title, const gchar *password_prompt, unsigned flags);
    74 void remmina_message_panel_setup_auth_x509(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data);
    75 void remmina_message_panel_focus_auth_entry(RemminaMessagePanel *mp);
    76 void remmina_message_panel_field_set_string(RemminaMessagePanel *mp, int entryid, const gchar *text);
    77 gchar *remmina_message_panel_field_get_string(RemminaMessagePanel *mp, int entryid);
    78 void remmina_message_panel_field_set_switch(RemminaMessagePanel *mp, int entryid, gboolean state);
    79 gboolean remmina_message_panel_field_get_switch_state(RemminaMessagePanel *mp, int entryid);
    80 void remmina_message_panel_field_set_filename(RemminaMessagePanel *mp, int entryid, const gchar *filename);
    81 gchar *remmina_message_panel_field_get_filename(RemminaMessagePanel *mp, int entryid);
    82 void remmina_message_panel_response(RemminaMessagePanel *mp, gint response_id);
    83 
    84 
    85 G_END_DECLS
    void remmina_message_panel_field_set_string(RemminaMessagePanel *mp, int entryid, const gchar *text)
    -
    void remmina_message_panel_setup_question(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    +
    void remmina_message_panel_setup_question(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    -
    void remmina_message_panel_setup_message(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    -
    gboolean remmina_message_panel_field_get_switch_state(RemminaMessagePanel *mp, int entryid)
    -
    gchar * remmina_message_panel_field_get_string(RemminaMessagePanel *mp, int entryid)
    -
    void remmina_message_panel_setup_progress(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    -
    void remmina_message_panel_focus_auth_entry(RemminaMessagePanel *mp)
    +
    void remmina_message_panel_setup_message(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    +
    gboolean remmina_message_panel_field_get_switch_state(RemminaMessagePanel *mp, int entryid)
    +
    gchar * remmina_message_panel_field_get_string(RemminaMessagePanel *mp, int entryid)
    +
    void remmina_message_panel_setup_progress(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    +
    void remmina_message_panel_focus_auth_entry(RemminaMessagePanel *mp)
    -
    void remmina_message_panel_response(RemminaMessagePanel *mp, gint response_id)
    +
    void remmina_message_panel_response(RemminaMessagePanel *mp, gint response_id)
    -
    RemminaMessagePanel * remmina_message_panel_new(void)
    -
    void remmina_message_panel_field_set_switch(RemminaMessagePanel *mp, int entryid, gboolean state)
    +
    RemminaMessagePanel * remmina_message_panel_new(void)
    +
    void remmina_message_panel_field_set_switch(RemminaMessagePanel *mp, int entryid, gboolean state)
    -
    gchar * remmina_message_panel_field_get_filename(RemminaMessagePanel *mp, int entryid)
    +
    gchar * remmina_message_panel_field_get_filename(RemminaMessagePanel *mp, int entryid)
    void(* RemminaMessagePanelCallback)(void *user_data, int button)
    -
    void remmina_message_panel_setup_auth_x509(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    +
    void remmina_message_panel_setup_auth_x509(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    -
    void remmina_message_panel_field_set_filename(RemminaMessagePanel *mp, int entryid, const gchar *filename)
    -
    void remmina_message_panel_setup_auth(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data, const gchar *title, const gchar *password_prompt, unsigned flags)
    +
    void remmina_message_panel_field_set_filename(RemminaMessagePanel *mp, int entryid, const gchar *filename)
    +
    void remmina_message_panel_setup_auth(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data, const gchar *title, const gchar *password_prompt, unsigned flags)
    G_DECLARE_DERIVABLE_TYPE(RemminaMessagePanel, remmina_message_panel, REMMINA, MESSAGE_PANEL, GtkBox) struct _RemminaMessagePanelClass
    diff --git a/public/remmina__mpchange_8c_source.html b/public/remmina__mpchange_8c_source.html index 5d47cb401..4cc9d8541 100644 --- a/public/remmina__mpchange_8c_source.html +++ b/public/remmina__mpchange_8c_source.html @@ -93,7 +93,7 @@ $(document).ready(function(){initNavTree('remmina__mpchange_8c_source.html','');
    const gchar * remmina_file_get_string(RemminaFile *remminafile, const gchar *setting)
    Definition: remmina_file.c:516
    guint searchentrychange_timeout_source_id
    static void remmina_mpchange_stopsearch(GtkSearchEntry *entry, gpointer user_data)
    -
    GtkWindow * remmina_main_get_window()
    +
    GtkWindow * remmina_main_get_window()
    GtkEntry * eGatewayPassword2
    diff --git a/public/remmina__plugin__manager_8c_source.html b/public/remmina__plugin__manager_8c_source.html index 1eed65f04..ce304aa72 100644 --- a/public/remmina__plugin__manager_8c_source.html +++ b/public/remmina__plugin__manager_8c_source.html @@ -101,7 +101,7 @@ $(document).ready(function(){initNavTree('remmina__plugin__manager_8c_source.htm
    static void htdestroy(gpointer ht)
    gchar * remmina_protocol_widget_start_direct_tunnel(RemminaProtocolWidget *gp, gint default_port, gboolean port_plus)
    Start an SSH tunnel if possible and return the host:port string.
    -
    GtkWindow * remmina_main_get_window()
    +
    GtkWindow * remmina_main_get_window()
    void remmina_protocol_widget_chat_receive(RemminaProtocolWidget *gp, const gchar *text)
    gint remmina_protocol_widget_get_width(RemminaProtocolWidget *gp)
    gboolean remmina_plugin_native_load(RemminaPluginService *service, const char *name)
    @@ -173,7 +173,7 @@ $(document).ready(function(){initNavTree('remmina__plugin__manager_8c_source.htm
    void remmina_protocol_widget_signal_connection_closed(RemminaProtocolWidget *gp)
    RemminaPluginService remmina_plugin_manager_service
    static const gchar * remmina_plugin_type_name[]
    -
    void remmina_main_show_dialog(GtkMessageType msg, GtkButtonsType buttons, const gchar *message)
    +
    void remmina_main_show_dialog(GtkMessageType msg, GtkButtonsType buttons, const gchar *message)
    void remmina_protocol_widget_desktop_resize(RemminaProtocolWidget *gp)
    RemminaProtocolFeatureType type
    Definition: types.h:73
    diff --git a/public/remmina__protocol__widget_8c_source.html b/public/remmina__protocol__widget_8c_source.html index ec2ac22e2..ec769c217 100644 --- a/public/remmina__protocol__widget_8c_source.html +++ b/public/remmina__protocol__widget_8c_source.html @@ -116,14 +116,14 @@ $(document).ready(function(){initNavTree('remmina__protocol__widget_8c_source.ht
    gboolean remmina_protocol_widget_query_feature_by_ref(RemminaProtocolWidget *gp, const RemminaProtocolFeature *feature)
    gboolean remmina_ssh_tunnel_reverse(RemminaSSHTunnel *tunnel, gint port, gint local_port)
    -
    void remmina_message_panel_setup_auth(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data, const gchar *title, const gchar *password_prompt, unsigned flags)
    +
    void remmina_message_panel_setup_auth(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data, const gchar *title, const gchar *password_prompt, unsigned flags)
    void(* call_feature)(RemminaProtocolWidget *gp, const RemminaProtocolFeature *feature)
    Definition: plugin.h:83
    static void remmina_protocol_widget_destroy(RemminaProtocolWidget *gp, gpointer data)
    static gboolean remmina_protocol_widget_dialog_mt_setup(gpointer user_data)
    -
    void remmina_message_panel_setup_question(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    +
    void remmina_message_panel_setup_question(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    void remmina_protocol_widget_chat_receive(RemminaProtocolWidget *gp, const gchar *text)
    -
    gchar * remmina_message_panel_field_get_filename(RemminaMessagePanel *mp, int entryid)
    +
    gchar * remmina_message_panel_field_get_filename(RemminaMessagePanel *mp, int entryid)
    gint remmina_protocol_widget_get_width(RemminaProtocolWidget *gp)
    gint remmina_protocol_widget_get_profile_remote_width(RemminaProtocolWidget *gp)
    @@ -152,7 +152,7 @@ $(document).ready(function(){initNavTree('remmina__protocol__widget_8c_source.ht
    gpointer destroy_func_callback_data
    Definition: remmina_ssh.h:181
    RemminaFile * remmina_file_dup_temp_protocol(RemminaFile *remminafile, const gchar *new_protocol)
    Definition: remmina_file.c:899
    GtkWidget * rcw_open_from_file_full(RemminaFile *remminafile, GCallback disconnect_cb, gpointer data, guint *handler)
    Definition: rcw.c:4499
    -
    void remmina_message_panel_setup_auth_x509(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    +
    void remmina_message_panel_setup_auth_x509(RemminaMessagePanel *mp, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    static int remmina_protocol_widget_dialog(enum panel_type dtype, RemminaProtocolWidget *gp, RemminaMessagePanelFlags pflags, const gchar *title, const gchar *default_username, const gchar *default_password, const gchar *default_domain, const gchar *strpasswordlabel)
    static void run_response_handler(RemminaMessagePanel *mp, gint response_id, gpointer data)
    @@ -193,7 +193,7 @@ $(document).ready(function(){initNavTree('remmina__protocol__widget_8c_source.ht
    gboolean(* open_connection)(RemminaProtocolWidget *gp)
    Definition: plugin.h:80
    RemminaMessagePanel * retry_message_panel
    -
    void remmina_message_panel_field_set_string(RemminaMessagePanel *mp, int entryid, const gchar *text)
    +
    void remmina_message_panel_field_set_string(RemminaMessagePanel *mp, int entryid, const gchar *text)
    RemminaProtocolPlugin * plugin
    static void run_unmap_handler(RemminaMessagePanel *mp, gpointer data)
    @@ -223,7 +223,7 @@ $(document).ready(function(){initNavTree('remmina__protocol__widget_8c_source.ht
    RemminaMessagePanelFlags
    Definition: types.h:155
    -
    void remmina_message_panel_field_set_filename(RemminaMessagePanel *mp, int entryid, const gchar *filename)
    +
    void remmina_message_panel_field_set_filename(RemminaMessagePanel *mp, int entryid, const gchar *filename)
    GtkWindow * rcw_get_gtkwindow(RemminaConnectionObject *cnnobj)
    Definition: rcw.c:4696
    gboolean remmina_masterthread_exec_is_main_thread()
    @@ -273,7 +273,7 @@ $(document).ready(function(){initNavTree('remmina__protocol__widget_8c_source.ht
    void remmina_protocol_widget_panel_show_retry(RemminaProtocolWidget *gp)
    void remmina_protocol_widget_send_clipboard(RemminaProtocolWidget *gp, GtkMenuItem *widget)
    -
    void remmina_message_panel_field_set_switch(RemminaMessagePanel *mp, int entryid, gboolean state)
    +
    void remmina_message_panel_field_set_switch(RemminaMessagePanel *mp, int entryid, gboolean state)
    gpointer callback_data
    Definition: remmina_ssh.h:178
    RemminaConnectionObject * cnnobj
    void remmina_protocol_widget_update_remote_resolution(RemminaProtocolWidget *gp)
    @@ -305,7 +305,7 @@ $(document).ready(function(){initNavTree('remmina__protocol__widget_8c_source.ht
    GtkWidget * rcw_get_gtkviewport(RemminaConnectionObject *cnnobj)
    Definition: rcw.c:4700
    void(* RemminaMessagePanelCallback)(void *user_data, int button)
    void remmina_protocol_widget_emit_signal(RemminaProtocolWidget *gp, const gchar *signal_name)
    -
    gchar * remmina_message_panel_field_get_string(RemminaMessagePanel *mp, int entryid)
    +
    gchar * remmina_message_panel_field_get_string(RemminaMessagePanel *mp, int entryid)
    RemminaTypeHint opt2_type_hint
    Definition: types.h:79
    gboolean remmina_protocol_widget_is_closed(RemminaProtocolWidget *gp)
    @@ -314,7 +314,7 @@ $(document).ready(function(){initNavTree('remmina__protocol__widget_8c_source.ht
    RemminaPref remmina_pref
    Definition: rcw.c:79
    static void run_destroy_handler(RemminaMessagePanel *mp, gpointer data)
    -
    void remmina_message_panel_setup_progress(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    +
    void remmina_message_panel_setup_progress(RemminaMessagePanel *mp, const gchar *message, RemminaMessagePanelCallback response_callback, gpointer response_callback_data)
    RemminaScaleMode
    Definition: types.h:141
    @@ -356,7 +356,7 @@ $(document).ready(function(){initNavTree('remmina__protocol__widget_8c_source.ht
    gboolean(* get_plugin_screenshot)(RemminaProtocolWidget *gp, RemminaPluginScreenshotData *rpsd)
    Definition: plugin.h:85
    void remmina_protocol_widget_set_expand(RemminaProtocolWidget *gp, gboolean expand)
    -
    gboolean remmina_message_panel_field_get_switch_state(RemminaMessagePanel *mp, int entryid)
    +
    gboolean remmina_message_panel_field_get_switch_state(RemminaMessagePanel *mp, int entryid)
    void remmina_file_set_string(RemminaFile *remminafile, const gchar *setting, const gchar *value)
    Definition: remmina_file.c:469
    void remmina_file_save(RemminaFile *remminafile)
    Definition: remmina_file.c:730
    @@ -383,9 +383,9 @@ $(document).ready(function(){initNavTree('remmina__protocol__widget_8c_source.ht
    gchar * localdisplay
    Definition: remmina_ssh.h:173
    gboolean(* RemminaXPortTunnelInitFunc)(RemminaProtocolWidget *gp, gint remotedisplay, const gchar *server, gint port)
    Definition: types.h:95
    -
    void remmina_message_panel_response(RemminaMessagePanel *mp, gint response_id)
    +
    void remmina_message_panel_response(RemminaMessagePanel *mp, gint response_id)
    void remmina_protocol_widget_chat_open(RemminaProtocolWidget *gp, const gchar *name, void(*on_send)(RemminaProtocolWidget *gp, const gchar *text), void(*on_destroy)(RemminaProtocolWidget *gp))
    -
    RemminaMessagePanel * remmina_message_panel_new()
    +
    RemminaMessagePanel * remmina_message_panel_new()
    RemminaTypeHint opt3_type_hint
    Definition: types.h:80
    RemminaSSHTunnelCallback connect_func
    Definition: remmina_ssh.h:176
    diff --git a/public/search/all_12.js b/public/search/all_12.js index ef0c69443..2ce78e11b 100644 --- a/public/search/all_12.js +++ b/public/search/all_12.js @@ -408,7 +408,6 @@ var searchData= ['remmina_5ffile_5fset_5fstring',['remmina_file_set_string',['../remmina__file_8c.html#a85ca1ca2d0bf9ef29e490c6f4527a954',1,'remmina_file_set_string(RemminaFile *remminafile, const gchar *setting, const gchar *value): remmina_file.c'],['../remmina__file_8h.html#a85ca1ca2d0bf9ef29e490c6f4527a954',1,'remmina_file_set_string(RemminaFile *remminafile, const gchar *setting, const gchar *value): remmina_file.c']]], ['remmina_5ffile_5fstate_5flast_5fsuccess',['remmina_file_state_last_success',['../remmina__file_8c.html#a493ffa77b862ff3bad9ea951592715a8',1,'remmina_file_state_last_success(RemminaFile *remminafile): remmina_file.c'],['../remmina__file_8h.html#a493ffa77b862ff3bad9ea951592715a8',1,'remmina_file_state_last_success(RemminaFile *remminafile): remmina_file.c']]], ['remmina_5ffile_5fstore_5fsecret_5fplugin_5fpassword',['remmina_file_store_secret_plugin_password',['../remmina__file_8c.html#a3be28ff7f5a9b44dc47f92b883a85ac5',1,'remmina_file_store_secret_plugin_password(RemminaFile *remminafile, const gchar *key, const gchar *value): remmina_file.c'],['../remmina__file_8h.html#a3be28ff7f5a9b44dc47f92b883a85ac5',1,'remmina_file_store_secret_plugin_password(RemminaFile *remminafile, const gchar *key, const gchar *value): remmina_file.c']]], - ['remmina_5ffile_5ftoggle_5fpassword_5fview',['remmina_file_toggle_password_view',['../remmina__file__editor_8c.html#a65b38bc13546d3d890624a79b080ffe9',1,'remmina_file_editor.c']]], ['remmina_5ffile_5ftouch',['remmina_file_touch',['../remmina__file_8c.html#a3d19095f74e9b7c92d74f11bd5a39a8c',1,'remmina_file_touch(RemminaFile *remminafile): remmina_file.c'],['../remmina__file_8h.html#a3d19095f74e9b7c92d74f11bd5a39a8c',1,'remmina_file_touch(RemminaFile *remminafile): remmina_file.c']]], ['remmina_5ffile_5funsave_5fpasswords',['remmina_file_unsave_passwords',['../remmina__file_8c.html#a503e53fe49430a5ed310c342c946c014',1,'remmina_file_unsave_passwords(RemminaFile *remminafile): remmina_file.c'],['../remmina__file_8h.html#a503e53fe49430a5ed310c342c946c014',1,'remmina_file_unsave_passwords(RemminaFile *remminafile): remmina_file.c']]], ['remmina_5ffilezilla_5fsftp_2esh',['remmina_filezilla_sftp.sh',['../remmina__filezilla__sftp_8sh.html',1,'']]], @@ -619,6 +618,7 @@ var searchData= ['remmina_5fmain_5fshow_5fdialog',['remmina_main_show_dialog',['../remmina__main_8c.html#ab2a1a54320992fb796850ffbd6a63589',1,'remmina_main_show_dialog(GtkMessageType msg, GtkButtonsType buttons, const gchar *message): remmina_main.c'],['../remmina__main_8h.html#ab2a1a54320992fb796850ffbd6a63589',1,'remmina_main_show_dialog(GtkMessageType msg, GtkButtonsType buttons, const gchar *message): remmina_main.c']]], ['remmina_5fmain_5fshow_5fsnap_5fwelcome',['remmina_main_show_snap_welcome',['../remmina__main_8c.html#ab08aae433b625c3a84330630fe2bd2d5',1,'remmina_main.c']]], ['remmina_5fmain_5fshow_5fwarning_5fdialog',['remmina_main_show_warning_dialog',['../remmina__main_8c.html#ad99b9c0bf2fa8c166a8b4a09e06ffdf7',1,'remmina_main_show_warning_dialog(const gchar *message): remmina_main.c'],['../remmina__main_8h.html#ad99b9c0bf2fa8c166a8b4a09e06ffdf7',1,'remmina_main_show_warning_dialog(const gchar *message): remmina_main.c']]], + ['remmina_5fmain_5ftoggle_5fpassword_5fview',['remmina_main_toggle_password_view',['../remmina__main_8c.html#aac3fe305e456dfa7bb55aa2f057e8cb0',1,'remmina_main_toggle_password_view(GtkWidget *widget, gpointer data): remmina_main.c'],['../remmina__main_8h.html#aac3fe305e456dfa7bb55aa2f057e8cb0',1,'remmina_main_toggle_password_view(GtkWidget *widget, gpointer data): remmina_main.c']]], ['remmina_5fmain_5ftree_5frow_5factivated',['remmina_main_tree_row_activated',['../remmina__main_8c.html#a4477897686d091d6f57e7f9401674a8c',1,'remmina_main.c']]], ['remmina_5fmain_5fupdate_5ffile_5fdatetime',['remmina_main_update_file_datetime',['../remmina__main_8c.html#a5ae0372dafe41f96a09097c07d1b270a',1,'remmina_main_update_file_datetime(RemminaFile *file): remmina_main.c'],['../remmina__main_8h.html#a5ae0372dafe41f96a09097c07d1b270a',1,'remmina_main_update_file_datetime(RemminaFile *file): remmina_main.c']]], ['remmina_5fmarshal_5fboolean_5f_5fint',['remmina_marshal_BOOLEAN__INT',['../remmina__marshals_8c.html#ae155b6ae758a6b0ef3d89a4458feec99',1,'remmina_marshal_BOOLEAN__INT(GClosure *closure, GValue *return_value G_GNUC_UNUSED, guint n_param_values, const GValue *param_values, gpointer invocation_hint G_GNUC_UNUSED, gpointer marshal_data): remmina_marshals.c'],['../remmina__marshals_8h.html#ab614355cdc97644b6505743b34a78384',1,'remmina_marshal_BOOLEAN__INT(GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data): remmina_marshals.h']]], diff --git a/public/search/functions_11.js b/public/search/functions_11.js index d81c6f61e..42d488647 100644 --- a/public/search/functions_11.js +++ b/public/search/functions_11.js @@ -283,7 +283,6 @@ var searchData= ['remmina_5ffile_5fset_5fstring',['remmina_file_set_string',['../remmina__file_8c.html#a85ca1ca2d0bf9ef29e490c6f4527a954',1,'remmina_file_set_string(RemminaFile *remminafile, const gchar *setting, const gchar *value): remmina_file.c'],['../remmina__file_8h.html#a85ca1ca2d0bf9ef29e490c6f4527a954',1,'remmina_file_set_string(RemminaFile *remminafile, const gchar *setting, const gchar *value): remmina_file.c']]], ['remmina_5ffile_5fstate_5flast_5fsuccess',['remmina_file_state_last_success',['../remmina__file_8c.html#a493ffa77b862ff3bad9ea951592715a8',1,'remmina_file_state_last_success(RemminaFile *remminafile): remmina_file.c'],['../remmina__file_8h.html#a493ffa77b862ff3bad9ea951592715a8',1,'remmina_file_state_last_success(RemminaFile *remminafile): remmina_file.c']]], ['remmina_5ffile_5fstore_5fsecret_5fplugin_5fpassword',['remmina_file_store_secret_plugin_password',['../remmina__file_8c.html#a3be28ff7f5a9b44dc47f92b883a85ac5',1,'remmina_file_store_secret_plugin_password(RemminaFile *remminafile, const gchar *key, const gchar *value): remmina_file.c'],['../remmina__file_8h.html#a3be28ff7f5a9b44dc47f92b883a85ac5',1,'remmina_file_store_secret_plugin_password(RemminaFile *remminafile, const gchar *key, const gchar *value): remmina_file.c']]], - ['remmina_5ffile_5ftoggle_5fpassword_5fview',['remmina_file_toggle_password_view',['../remmina__file__editor_8c.html#a65b38bc13546d3d890624a79b080ffe9',1,'remmina_file_editor.c']]], ['remmina_5ffile_5ftouch',['remmina_file_touch',['../remmina__file_8c.html#a3d19095f74e9b7c92d74f11bd5a39a8c',1,'remmina_file_touch(RemminaFile *remminafile): remmina_file.c'],['../remmina__file_8h.html#a3d19095f74e9b7c92d74f11bd5a39a8c',1,'remmina_file_touch(RemminaFile *remminafile): remmina_file.c']]], ['remmina_5ffile_5funsave_5fpasswords',['remmina_file_unsave_passwords',['../remmina__file_8c.html#a503e53fe49430a5ed310c342c946c014',1,'remmina_file_unsave_passwords(RemminaFile *remminafile): remmina_file.c'],['../remmina__file_8h.html#a503e53fe49430a5ed310c342c946c014',1,'remmina_file_unsave_passwords(RemminaFile *remminafile): remmina_file.c']]], ['remmina_5fftp_5fclient_5faction_5fdelete',['remmina_ftp_client_action_delete',['../remmina__ftp__client_8c.html#a5a433db0f6129e0bc4ec2fdc8f7588f6',1,'remmina_ftp_client.c']]], @@ -445,6 +444,7 @@ var searchData= ['remmina_5fmain_5fshow_5fdialog',['remmina_main_show_dialog',['../remmina__main_8c.html#ab2a1a54320992fb796850ffbd6a63589',1,'remmina_main_show_dialog(GtkMessageType msg, GtkButtonsType buttons, const gchar *message): remmina_main.c'],['../remmina__main_8h.html#ab2a1a54320992fb796850ffbd6a63589',1,'remmina_main_show_dialog(GtkMessageType msg, GtkButtonsType buttons, const gchar *message): remmina_main.c']]], ['remmina_5fmain_5fshow_5fsnap_5fwelcome',['remmina_main_show_snap_welcome',['../remmina__main_8c.html#ab08aae433b625c3a84330630fe2bd2d5',1,'remmina_main.c']]], ['remmina_5fmain_5fshow_5fwarning_5fdialog',['remmina_main_show_warning_dialog',['../remmina__main_8c.html#ad99b9c0bf2fa8c166a8b4a09e06ffdf7',1,'remmina_main_show_warning_dialog(const gchar *message): remmina_main.c'],['../remmina__main_8h.html#ad99b9c0bf2fa8c166a8b4a09e06ffdf7',1,'remmina_main_show_warning_dialog(const gchar *message): remmina_main.c']]], + ['remmina_5fmain_5ftoggle_5fpassword_5fview',['remmina_main_toggle_password_view',['../remmina__main_8c.html#aac3fe305e456dfa7bb55aa2f057e8cb0',1,'remmina_main_toggle_password_view(GtkWidget *widget, gpointer data): remmina_main.c'],['../remmina__main_8h.html#aac3fe305e456dfa7bb55aa2f057e8cb0',1,'remmina_main_toggle_password_view(GtkWidget *widget, gpointer data): remmina_main.c']]], ['remmina_5fmain_5ftree_5frow_5factivated',['remmina_main_tree_row_activated',['../remmina__main_8c.html#a4477897686d091d6f57e7f9401674a8c',1,'remmina_main.c']]], ['remmina_5fmain_5fupdate_5ffile_5fdatetime',['remmina_main_update_file_datetime',['../remmina__main_8c.html#a5ae0372dafe41f96a09097c07d1b270a',1,'remmina_main_update_file_datetime(RemminaFile *file): remmina_main.c'],['../remmina__main_8h.html#a5ae0372dafe41f96a09097c07d1b270a',1,'remmina_main_update_file_datetime(RemminaFile *file): remmina_main.c']]], ['remmina_5fmarshal_5fboolean_5f_5fint',['remmina_marshal_BOOLEAN__INT',['../remmina__marshals_8c.html#ae155b6ae758a6b0ef3d89a4458feec99',1,'remmina_marshal_BOOLEAN__INT(GClosure *closure, GValue *return_value G_GNUC_UNUSED, guint n_param_values, const GValue *param_values, gpointer invocation_hint G_GNUC_UNUSED, gpointer marshal_data): remmina_marshals.c'],['../remmina__marshals_8h.html#ab614355cdc97644b6505743b34a78384',1,'remmina_marshal_BOOLEAN__INT(GClosure *closure, GValue *return_value, guint n_param_values, const GValue *param_values, gpointer invocation_hint, gpointer marshal_data): remmina_marshals.h']]], diff --git a/public/struct_remmina_message_panel_private.html b/public/struct_remmina_message_panel_private.html index c1921f01e..69decd946 100644 --- a/public/struct_remmina_message_panel_private.html +++ b/public/struct_remmina_message_panel_private.html @@ -100,7 +100,7 @@ Data Fields

    Detailed Description

    -

    Definition at line 46 of file remmina_message_panel.c.

    +

    Definition at line 47 of file remmina_message_panel.c.

    Field Documentation

    ◆ response_callback

    @@ -114,7 +114,7 @@ Data Fields
    -

    Definition at line 49 of file remmina_message_panel.c.

    +

    Definition at line 50 of file remmina_message_panel.c.

    @@ -130,7 +130,7 @@ Data Fields
    -

    Definition at line 50 of file remmina_message_panel.c.

    +

    Definition at line 51 of file remmina_message_panel.c.

    @@ -146,7 +146,7 @@ Data Fields
    -

    Definition at line 51 of file remmina_message_panel.c.

    +

    Definition at line 52 of file remmina_message_panel.c.

    -- cgit v1.2.3