Commit 492c107db46afba5c9d4e93edfb840d9eb974a2e

Authored by Perry Werneck
1 parent 9d4b500e

Implementing context based popup menus.

src/objects/window/private.h
... ... @@ -46,6 +46,16 @@
46 46 #include <lib3270.h>
47 47 #include <lib3270/log.h>
48 48  
  49 + enum pw3270ApplicationWindowPopup {
  50 + PW3270_APP_WINDOW_POPUP_OVER_SELECTED_AREA,
  51 + PW3270_APP_WINDOW_POPUP_OVER_UNSELECTED_AREA,
  52 + PW3270_APP_WINDOW_POPUP_WHEN_OFFLINE,
  53 +
  54 + PW3270_APP_WINDOW_POPUP_COUNT
  55 + };
  56 +
  57 + #define PW3270_APP_WINDOW_POPUP_DEFAULT PW3270_APP_WINDOW_POPUP_OVER_UNSELECTED_AREA
  58 +
49 59 struct _pw3270ApplicationWindow {
50 60  
51 61 GtkApplicationWindow parent;
... ... @@ -53,6 +63,8 @@
53 63 GtkNotebook * notebook;
54 64 GtkToolbar * toolbar;
55 65  
  66 + GtkWidget * popups[PW3270_APP_WINDOW_POPUP_COUNT];
  67 +
56 68 };
57 69  
58 70 struct _pw3270ApplicationWindowClass {
... ...
src/objects/window/terminal.c
... ... @@ -149,6 +149,28 @@
149 149  
150 150 }
151 151  
  152 + static gboolean on_popup_menu(GtkWidget *widget, gboolean selected, gboolean online, GdkEvent *event, pw3270ApplicationWindow * window) {
  153 +
  154 + GtkWidget * popup = window->popups[PW3270_APP_WINDOW_POPUP_OVER_UNSELECTED_AREA];
  155 +
  156 + if(!online && window->popups[PW3270_APP_WINDOW_POPUP_WHEN_OFFLINE])
  157 + popup = window->popups[PW3270_APP_WINDOW_POPUP_WHEN_OFFLINE];
  158 + else if(selected && window->popups[PW3270_APP_WINDOW_POPUP_OVER_SELECTED_AREA])
  159 + popup = window->popups[PW3270_APP_WINDOW_POPUP_OVER_SELECTED_AREA];
  160 + else
  161 + popup = window->popups[PW3270_APP_WINDOW_POPUP_DEFAULT];
  162 +
  163 + if(!popup)
  164 + return FALSE;
  165 +
  166 + gtk_widget_show_all(popup);
  167 + gtk_menu_set_screen(GTK_MENU(popup), gtk_widget_get_screen(widget));
  168 + gtk_menu_popup_at_pointer(GTK_MENU(popup), event);
  169 +
  170 + return TRUE;
  171 +
  172 + }
  173 +
152 174 static gint append_terminal_page(pw3270ApplicationWindow * window, GtkWidget * terminal) {
153 175  
154 176 GtkWidget * label = gtk_label_new(v3270_get_session_name(terminal));
... ... @@ -164,6 +186,7 @@
164 186 g_signal_connect(G_OBJECT(terminal), "disconnected", G_CALLBACK(disconnected),window);
165 187 g_signal_connect(G_OBJECT(terminal), "connected", G_CALLBACK(connected),window);
166 188 g_signal_connect(G_OBJECT(terminal), "destroy", G_CALLBACK(on_terminal_destroy),window);
  189 + g_signal_connect(G_OBJECT(terminal), "popup", G_CALLBACK(on_popup_menu), window);
167 190  
168 191 g_signal_connect(G_OBJECT(button), "clicked", G_CALLBACK(on_close_tab), terminal);
169 192  
... ...
src/objects/window/window.c
... ... @@ -37,10 +37,13 @@
37 37  
38 38 static void destroy(GtkWidget *widget) {
39 39  
  40 + size_t ix;
  41 + pw3270ApplicationWindow * window = PW3270_APPLICATION_WINDOW(widget);
  42 +
  43 +
40 44 debug("%s(%p)",__FUNCTION__,widget);
41 45  
42 46 // Update actions
43   - size_t ix;
44 47 gchar ** actions = g_action_group_list_actions(G_ACTION_GROUP(widget));
45 48  
46 49 for(ix = 0; actions[ix]; ix++) {
... ... @@ -54,6 +57,15 @@
54 57  
55 58 g_strfreev(actions);
56 59  
  60 + // Destroy popups
  61 + for(ix = 0; ix < G_N_ELEMENTS(window->popups); ix++) {
  62 + if(window->popups[ix]) {
  63 + gtk_widget_destroy(window->popups[ix]);
  64 + window->popups[ix] = NULL;
  65 + }
  66 + }
  67 +
  68 +
57 69 GTK_WIDGET_CLASS(pw3270ApplicationWindow_parent_class)->destroy(widget);
58 70  
59 71 }
... ... @@ -179,6 +191,7 @@
179 191  
180 192 GtkWidget * pw3270_application_window_new(GtkApplication * application) {
181 193  
  194 + size_t ix;
182 195 const gchar * title = _( "IBM 3270 Terminal emulator" );
183 196  
184 197 g_autoptr(GSettings) settings = pw3270_application_get_settings(G_APPLICATION(application));
... ... @@ -235,6 +248,24 @@
235 248 g_warning("Unexpected UI");
236 249  
237 250 }
  251 +
  252 + // Load popup menus.
  253 + const gchar * popup_menus[G_N_ELEMENTS(window->popups)] = {
  254 + "popup-over-selected-area",
  255 + "popup-over-unselected-area",
  256 + "popup-when-offline"
  257 + };
  258 +
  259 + for(ix = 0; ix < G_N_ELEMENTS(popup_menus); ix++) {
  260 +
  261 + GObject * model = gtk_builder_get_object(builder, popup_menus[ix]);
  262 + if(model) {
  263 + window->popups[ix] = gtk_menu_new_from_model(G_MENU_MODEL(model));
  264 + gtk_menu_attach_to_widget(GTK_MENU(window->popups[ix]),GTK_WIDGET(window),NULL);
  265 + }
  266 +
  267 + }
  268 +
238 269 g_object_unref(builder);
239 270  
240 271 }
... ...
ui/window.xml
... ... @@ -69,4 +69,106 @@
69 69 </item>
70 70 </section>
71 71 </menu>
  72 +
  73 + <menu id="popup-over-selected-area">
  74 +
  75 + <section>
  76 +
  77 + <item>
  78 + <attribute name="label" translatable="yes">Save selected</attribute>
  79 + <attribute name="action">win.save_selected</attribute>
  80 + </item>
  81 +
  82 + <item>
  83 + <attribute name="label" translatable="yes">Print selected</attribute>
  84 + <attribute name="action">win.print_selected</attribute>
  85 + </item>
  86 +
  87 + </section>
  88 +
  89 + <section>
  90 +
  91 + <item>
  92 + <attribute name="label" translatable="yes">Show toolbar</attribute>
  93 + <attribute name="action">win.toolbar</attribute>
  94 + </item>
  95 +
  96 + <item>
  97 + <attribute name="label" translatable="yes">Show menu</attribute>
  98 + <attribute name="action">win.menubar</attribute>
  99 + </item>
  100 +
  101 + </section>
  102 +
  103 + </menu>
  104 +
  105 + <menu id="popup-over-unselected-area">
  106 +
  107 + <section>
  108 +
  109 + <item>
  110 + <attribute name="label" translatable="yes">Send/Receive files</attribute>
  111 + <attribute name="action">win.file.transfer</attribute>
  112 + </item>
  113 +
  114 + <item>
  115 + <attribute name="label" translatable="yes">Disconnect</attribute>
  116 + <attribute name="action">win.disconnect</attribute>
  117 + </item>
  118 +
  119 + </section>
  120 +
  121 + <section>
  122 +
  123 + <item>
  124 + <attribute name="label" translatable="yes">Show toolbar</attribute>
  125 + <attribute name="action">win.toolbar</attribute>
  126 + </item>
  127 +
  128 + <item>
  129 + <attribute name="label" translatable="yes">Show menu</attribute>
  130 + <attribute name="action">win.menubar</attribute>
  131 + </item>
  132 +
  133 + </section>
  134 +
  135 + </menu>
  136 +
  137 + <menu id="popup-when-offline">
  138 +
  139 + <section>
  140 +
  141 + <item>
  142 + <attribute name="label" translatable="yes">_Connect</attribute>
  143 + <attribute name="action">win.connect</attribute>
  144 + </item>
  145 +
  146 + <item>
  147 + <attribute name="label" translatable="yes">Configure host</attribute>
  148 + <attribute name="action">win.set.host</attribute>
  149 + </item>
  150 +
  151 + </section>
  152 +
  153 + <section>
  154 +
  155 + <item>
  156 + <attribute name="label" translatable="yes">Show toolbar</attribute>
  157 + <attribute name="action">win.toolbar</attribute>
  158 + </item>
  159 +
  160 + <item>
  161 + <attribute name="label" translatable="yes">Show menu</attribute>
  162 + <attribute name="action">win.menubar</attribute>
  163 + </item>
  164 +
  165 + </section>
  166 +
  167 + <item>
  168 + <attribute name="label" translatable="yes">Quit application</attribute>
  169 + <attribute name="action">app.quit</attribute>
  170 + </item>
  171 +
  172 + </menu>
  173 +
72 174 </interface>
... ...