Commit bc786932e5d28a63bc544cc032714c088491976f
1 parent
dbbac7ef
Exists in
master
and in
2 other branches
Reorganizing folders to avoid confusion with the object window and OS
windows.
Showing
5 changed files
with
582 additions
and
582 deletions
Show diff stats
Makefile.in
... | ... | @@ -38,7 +38,7 @@ SOURCES= \ |
38 | 38 | $(wildcard src/objects/terminal/*.c) \ |
39 | 39 | $(wildcard src/objects/toolbar/*.c) \ |
40 | 40 | $(wildcard src/objects/settings/*.c) \ |
41 | - $(wildcard src/objects/@OSNAME@/*.c) \ | |
41 | + $(wildcard src/objects/os/@OSNAME@/*.c) \ | |
42 | 42 | $(wildcard src/main/*.c) \ |
43 | 43 | $(wildcard src/main/@OSNAME@/*.c) \ |
44 | 44 | $(wildcard src/main/@OSNAME@/*.rc) \ | ... | ... |
src/objects/linux/savedesktopicon.c
... | ... | @@ -1,308 +0,0 @@ |
1 | -/* | |
2 | - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 | |
3 | - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a | |
4 | - * aplicativos mainframe. Registro no INPI sob o nome G3270. | |
5 | - * | |
6 | - * Copyright (C) <2008> <Banco do Brasil S.A.> | |
7 | - * | |
8 | - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob | |
9 | - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela | |
10 | - * Free Software Foundation. | |
11 | - * | |
12 | - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER | |
13 | - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO | |
14 | - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para | |
15 | - * obter mais detalhes. | |
16 | - * | |
17 | - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este | |
18 | - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin | |
19 | - * St, Fifth Floor, Boston, MA 02110-1301 USA | |
20 | - * | |
21 | - * Este programa está nomeado como - e possui - linhas de código. | |
22 | - * | |
23 | - * Contatos: | |
24 | - * | |
25 | - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) | |
26 | - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) | |
27 | - * | |
28 | - */ | |
29 | - | |
30 | - /** | |
31 | - * @brief Implement Linux version of the save desktop icon action. | |
32 | - * | |
33 | - */ | |
34 | - | |
35 | - #include <v3270.h> | |
36 | - #include <pw3270.h> | |
37 | - #include <pw3270/application.h> | |
38 | - #include <v3270/actions.h> | |
39 | - #include <v3270/keyfile.h> | |
40 | - #include <lib3270.h> | |
41 | - #include <lib3270/log.h> | |
42 | - | |
43 | - static GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal); | |
44 | - static void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal); | |
45 | - | |
46 | -/* | |
47 | - | |
48 | -[Desktop Entry] | |
49 | -GenericName=pw3270 | |
50 | -Name=pw3270 | |
51 | -Comment=Comment | |
52 | -Exec=/usr/bin/sisbb | |
53 | -Icon=pw3270 | |
54 | -Terminal=false | |
55 | -Type=Application | |
56 | -StartupNotify=true | |
57 | -Categories=GTK;GNOME;TerminalEmulator | |
58 | -OnlyShowIn=GNOME;Unity | |
59 | -X-Desktop-File-Install-Version=0.23 | |
60 | -*/ | |
61 | - | |
62 | - static const struct _entry { | |
63 | - | |
64 | - const gchar * key; | |
65 | - const gchar * label; | |
66 | - const gchar * tooltip; | |
67 | - const gchar * default_value; | |
68 | - gint width; | |
69 | -// gint n_chars; | |
70 | - | |
71 | - } entries[] = { | |
72 | - | |
73 | - { | |
74 | - .label = N_("File name"), | |
75 | - .width = 40, | |
76 | - }, | |
77 | - | |
78 | - { | |
79 | - .key = "Name", | |
80 | - .label = N_("Launcher name"), | |
81 | - .default_value = G_STRINGIFY(PRODUCT_NAME), | |
82 | - .width = 20, | |
83 | - }, | |
84 | - | |
85 | - { | |
86 | - .key = "GenericName", | |
87 | - .label = N_("Generic name"), | |
88 | - .default_value = G_STRINGIFY(PRODUCT_NAME), | |
89 | - .width = 20, | |
90 | - }, | |
91 | - | |
92 | - { | |
93 | - .key = "Comment", | |
94 | - .label = N_("Comment"), | |
95 | - .default_value = N_("IBM 3270 Terminal emulator"), | |
96 | - .width = 30, | |
97 | - } | |
98 | - | |
99 | - }; | |
100 | - | |
101 | - GAction * pw3270_action_save_desktop_icon_new(void) { | |
102 | - | |
103 | - V3270SimpleAction * action = v3270_dialog_action_new(factory); | |
104 | - | |
105 | - action->name = "save.launcher"; | |
106 | - action->label = _("Save desktop icon"); | |
107 | - action->tooltip = _("Create a desktop icon for the current session"); | |
108 | - | |
109 | - return G_ACTION(action); | |
110 | - | |
111 | - } | |
112 | - | |
113 | - GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal) { | |
114 | - | |
115 | - size_t ix; | |
116 | - | |
117 | - gboolean use_header; | |
118 | - g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL); | |
119 | - | |
120 | - GtkWidget * dialog = | |
121 | - GTK_WIDGET(g_object_new( | |
122 | - GTK_TYPE_DIALOG, | |
123 | - "use-header-bar", (use_header ? 1 : 0), | |
124 | - NULL | |
125 | - )); | |
126 | - | |
127 | - | |
128 | - gtk_window_set_modal(GTK_WINDOW(dialog),TRUE); | |
129 | - gtk_window_set_title(GTK_WINDOW(dialog),action->label); | |
130 | - | |
131 | - gtk_dialog_add_buttons( | |
132 | - GTK_DIALOG(dialog), | |
133 | - _("_Cancel"), GTK_RESPONSE_CANCEL, | |
134 | - _("_Save"), GTK_RESPONSE_APPLY, | |
135 | - NULL | |
136 | - ); | |
137 | - | |
138 | - g_signal_connect(dialog,"response",G_CALLBACK(response),terminal); | |
139 | - | |
140 | - // Create entry fields | |
141 | - GtkWidget ** inputs = g_new0(GtkWidget *,G_N_ELEMENTS(entries)); | |
142 | - g_object_set_data_full(G_OBJECT(dialog),"inputs",inputs,g_free); | |
143 | - debug("Dialog=%p inputs=%p",dialog,inputs); | |
144 | - | |
145 | - GtkGrid * grid = GTK_GRID(gtk_grid_new()); | |
146 | - | |
147 | - gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),GTK_WIDGET(grid),TRUE,TRUE,0); | |
148 | - | |
149 | - // https://developer.gnome.org/hig/stable/visual-layout.html.en | |
150 | - gtk_container_set_border_width(GTK_CONTAINER(grid),18); | |
151 | - gtk_grid_set_row_spacing(GTK_GRID(grid),6); | |
152 | - gtk_grid_set_column_spacing(GTK_GRID(grid),12); | |
153 | - | |
154 | - // https://developer.gnome.org/hig/stable/visual-layout.html.en | |
155 | - // gtk_box_set_spacing(GTK_BOX(content_area),18); | |
156 | - | |
157 | - for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) { | |
158 | - | |
159 | - GtkWidget * label = gtk_label_new(gettext(entries[ix].label)); | |
160 | - gtk_label_set_xalign(GTK_LABEL(label),1); | |
161 | - gtk_grid_attach(grid,label,0,ix,1,1); | |
162 | - | |
163 | - inputs[ix] = gtk_entry_new(); | |
164 | - debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]); | |
165 | - | |
166 | - if(entries[ix].default_value) { | |
167 | - gtk_entry_set_text(GTK_ENTRY(inputs[ix]),gettext(entries[ix].default_value)); | |
168 | - } | |
169 | - | |
170 | - gtk_entry_set_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].width); | |
171 | -// gtk_entry_set_max_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].n_chars); | |
172 | - gtk_widget_set_hexpand(inputs[ix],FALSE); | |
173 | - gtk_widget_set_vexpand(inputs[ix],FALSE); | |
174 | - | |
175 | - gtk_grid_attach(grid,inputs[ix],1,ix,entries[ix].width,1); | |
176 | - | |
177 | - } | |
178 | - | |
179 | - g_autofree gchar * filename = g_strdup_printf("%s/" G_STRINGIFY(PRODUCT_NAME) ".desktop",g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP)); | |
180 | - | |
181 | - gtk_entry_set_text(GTK_ENTRY(inputs[0]),filename); | |
182 | - | |
183 | - /* | |
184 | - gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[1]),G_STRINGIFY(PRODUCT_NAME)); | |
185 | - gtk_entry_set_text(GTK_ENTRY(inputs[1]),G_STRINGIFY(PRODUCT_NAME)); | |
186 | - | |
187 | - gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[2]),G_STRINGIFY(PRODUCT_NAME)); | |
188 | - gtk_entry_set_text(GTK_ENTRY(inputs[2]),G_STRINGIFY(PRODUCT_NAME)); | |
189 | - */ | |
190 | - | |
191 | - gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[3]),v3270_get_url(terminal)); | |
192 | - gtk_entry_set_text(GTK_ENTRY(inputs[3]),v3270_get_url(terminal)); | |
193 | - gtk_entry_set_input_hints(GTK_ENTRY(inputs[3]),GTK_INPUT_HINT_SPELLCHECK); | |
194 | - | |
195 | - gtk_widget_show_all(GTK_WIDGET(grid)); | |
196 | - return dialog; | |
197 | - } | |
198 | - | |
199 | - void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal) { | |
200 | - | |
201 | - debug("%s(%d)",__FUNCTION__,response_id); | |
202 | - | |
203 | - if(response_id == GTK_RESPONSE_APPLY) { | |
204 | - | |
205 | - static const char * key_file_data = | |
206 | - "[Desktop Entry]\n" \ | |
207 | - "Icon=" G_STRINGIFY(PRODUCT_NAME) "\n" \ | |
208 | - "Terminal=false\n" \ | |
209 | - "Type=Application\n" \ | |
210 | - "StartupNotify=true\n" \ | |
211 | - "Categories=GTK;GNOME;TerminalEmulator\n" \ | |
212 | - "OnlyShowIn=GNOME;Unity\n"; | |
213 | - | |
214 | - GError * error = NULL; | |
215 | - size_t ix; | |
216 | - | |
217 | - GKeyFile * keyfile = g_key_file_new(); | |
218 | - g_key_file_load_from_data(keyfile,key_file_data,-1,G_KEY_FILE_NONE,NULL); | |
219 | - | |
220 | -#ifdef DEBUG | |
221 | - { | |
222 | - g_autofree gchar * dbg_data = g_key_file_to_data(keyfile,NULL,NULL); | |
223 | - debug("\n%s\n",dbg_data); | |
224 | - } | |
225 | -#endif // DEBUG | |
226 | - | |
227 | - | |
228 | - GtkWidget ** inputs = g_object_get_data(G_OBJECT(dialog),"inputs"); | |
229 | - debug("dialog=%p inputs=%p",dialog,inputs); | |
230 | - | |
231 | - for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) { | |
232 | - if(entries[ix].key) { | |
233 | - debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]); | |
234 | - g_key_file_set_string(keyfile,"Desktop Entry",entries[ix].key,gtk_entry_get_text(GTK_ENTRY(inputs[ix]))); | |
235 | - } | |
236 | - } | |
237 | - | |
238 | - // Get session filename | |
239 | - /* | |
240 | - const gchar * session_file = v3270_get_session_filename(terminal); | |
241 | - | |
242 | - if(!session_file) { | |
243 | - | |
244 | - // No session file, create one. | |
245 | - | |
246 | - // Check for configdir | |
247 | - g_autofree gchar * configdir = g_build_filename(g_get_user_config_dir(),G_STRINGIFY(PRODUCT_NAME),"sessions",NULL); | |
248 | - g_mkdir_with_parents(configdir,0755); | |
249 | - | |
250 | - // Create a base name | |
251 | - g_autofree gchar * basename = g_path_get_basename(gtk_entry_get_text(GTK_ENTRY(inputs[0]))); | |
252 | - | |
253 | - gchar *ptr = strrchr(basename,'.'); | |
254 | - if(ptr) | |
255 | - *ptr = 0; | |
256 | - | |
257 | - ix = time(NULL); | |
258 | - gchar * new_session_file = g_strdup_printf("%s/%s.3270",configdir,basename); | |
259 | - while(!g_file_test(new_session_file,G_FILE_TEST_EXISTS)) { | |
260 | - g_free(new_session_file); | |
261 | - new_session_file = g_strdup_printf("%s/%s_%08lx.3270",configdir,basename,(unsigned long) ix++); | |
262 | - } | |
263 | - | |
264 | - g_message("Saving session to %s",new_session_file); | |
265 | - v3270_set_session_filename(terminal,new_session_file); | |
266 | - g_free(new_session_file); | |
267 | - | |
268 | - } | |
269 | - */ | |
270 | - | |
271 | - // Get program file name | |
272 | - // https://stackoverflow.com/questions/4517425/how-to-get-program-path | |
273 | - { | |
274 | - char buffer[4096]; | |
275 | - g_autofree gchar * pidfile = g_strdup_printf("/proc/%d/exe", getpid()); | |
276 | - | |
277 | - int bytes = readlink(pidfile,buffer,4095); | |
278 | - | |
279 | - if(bytes >= 0) | |
280 | - buffer[bytes] = '\0'; | |
281 | - | |
282 | - g_autofree gchar * exec_line = g_strdup_printf("%s \"%s\"",buffer,v3270_key_file_get_file_name(terminal)); | |
283 | - g_key_file_set_string(keyfile,"Desktop Entry","Exec",exec_line); | |
284 | - | |
285 | - } | |
286 | - | |
287 | - g_key_file_save_to_file(keyfile,gtk_entry_get_text(GTK_ENTRY(inputs[0])),&error); | |
288 | - | |
289 | - if(error) { | |
290 | - | |
291 | - g_message("%s",error->message); | |
292 | - | |
293 | - | |
294 | - g_error_free(error); | |
295 | - | |
296 | - } else { | |
297 | - | |
298 | - g_message("File \"%s\" was saved",gtk_entry_get_text(GTK_ENTRY(inputs[0]))); | |
299 | - | |
300 | - } | |
301 | - | |
302 | - | |
303 | - g_key_file_free(keyfile); | |
304 | - } | |
305 | - | |
306 | - gtk_widget_destroy(dialog); | |
307 | - | |
308 | -} |
... | ... | @@ -0,0 +1,308 @@ |
1 | +/* | |
2 | + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 | |
3 | + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a | |
4 | + * aplicativos mainframe. Registro no INPI sob o nome G3270. | |
5 | + * | |
6 | + * Copyright (C) <2008> <Banco do Brasil S.A.> | |
7 | + * | |
8 | + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob | |
9 | + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela | |
10 | + * Free Software Foundation. | |
11 | + * | |
12 | + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER | |
13 | + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO | |
14 | + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para | |
15 | + * obter mais detalhes. | |
16 | + * | |
17 | + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este | |
18 | + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin | |
19 | + * St, Fifth Floor, Boston, MA 02110-1301 USA | |
20 | + * | |
21 | + * Este programa está nomeado como - e possui - linhas de código. | |
22 | + * | |
23 | + * Contatos: | |
24 | + * | |
25 | + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) | |
26 | + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) | |
27 | + * | |
28 | + */ | |
29 | + | |
30 | + /** | |
31 | + * @brief Implement Linux version of the save desktop icon action. | |
32 | + * | |
33 | + */ | |
34 | + | |
35 | + #include <v3270.h> | |
36 | + #include <pw3270.h> | |
37 | + #include <pw3270/application.h> | |
38 | + #include <v3270/actions.h> | |
39 | + #include <v3270/keyfile.h> | |
40 | + #include <lib3270.h> | |
41 | + #include <lib3270/log.h> | |
42 | + | |
43 | + static GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal); | |
44 | + static void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal); | |
45 | + | |
46 | +/* | |
47 | + | |
48 | +[Desktop Entry] | |
49 | +GenericName=pw3270 | |
50 | +Name=pw3270 | |
51 | +Comment=Comment | |
52 | +Exec=/usr/bin/sisbb | |
53 | +Icon=pw3270 | |
54 | +Terminal=false | |
55 | +Type=Application | |
56 | +StartupNotify=true | |
57 | +Categories=GTK;GNOME;TerminalEmulator | |
58 | +OnlyShowIn=GNOME;Unity | |
59 | +X-Desktop-File-Install-Version=0.23 | |
60 | +*/ | |
61 | + | |
62 | + static const struct _entry { | |
63 | + | |
64 | + const gchar * key; | |
65 | + const gchar * label; | |
66 | + const gchar * tooltip; | |
67 | + const gchar * default_value; | |
68 | + gint width; | |
69 | +// gint n_chars; | |
70 | + | |
71 | + } entries[] = { | |
72 | + | |
73 | + { | |
74 | + .label = N_("File name"), | |
75 | + .width = 40, | |
76 | + }, | |
77 | + | |
78 | + { | |
79 | + .key = "Name", | |
80 | + .label = N_("Launcher name"), | |
81 | + .default_value = G_STRINGIFY(PRODUCT_NAME), | |
82 | + .width = 20, | |
83 | + }, | |
84 | + | |
85 | + { | |
86 | + .key = "GenericName", | |
87 | + .label = N_("Generic name"), | |
88 | + .default_value = G_STRINGIFY(PRODUCT_NAME), | |
89 | + .width = 20, | |
90 | + }, | |
91 | + | |
92 | + { | |
93 | + .key = "Comment", | |
94 | + .label = N_("Comment"), | |
95 | + .default_value = N_("IBM 3270 Terminal emulator"), | |
96 | + .width = 30, | |
97 | + } | |
98 | + | |
99 | + }; | |
100 | + | |
101 | + GAction * pw3270_action_save_desktop_icon_new(void) { | |
102 | + | |
103 | + V3270SimpleAction * action = v3270_dialog_action_new(factory); | |
104 | + | |
105 | + action->name = "save.launcher"; | |
106 | + action->label = _("Save desktop icon"); | |
107 | + action->tooltip = _("Create a desktop icon for the current session"); | |
108 | + | |
109 | + return G_ACTION(action); | |
110 | + | |
111 | + } | |
112 | + | |
113 | + GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal) { | |
114 | + | |
115 | + size_t ix; | |
116 | + | |
117 | + gboolean use_header; | |
118 | + g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL); | |
119 | + | |
120 | + GtkWidget * dialog = | |
121 | + GTK_WIDGET(g_object_new( | |
122 | + GTK_TYPE_DIALOG, | |
123 | + "use-header-bar", (use_header ? 1 : 0), | |
124 | + NULL | |
125 | + )); | |
126 | + | |
127 | + | |
128 | + gtk_window_set_modal(GTK_WINDOW(dialog),TRUE); | |
129 | + gtk_window_set_title(GTK_WINDOW(dialog),action->label); | |
130 | + | |
131 | + gtk_dialog_add_buttons( | |
132 | + GTK_DIALOG(dialog), | |
133 | + _("_Cancel"), GTK_RESPONSE_CANCEL, | |
134 | + _("_Save"), GTK_RESPONSE_APPLY, | |
135 | + NULL | |
136 | + ); | |
137 | + | |
138 | + g_signal_connect(dialog,"response",G_CALLBACK(response),terminal); | |
139 | + | |
140 | + // Create entry fields | |
141 | + GtkWidget ** inputs = g_new0(GtkWidget *,G_N_ELEMENTS(entries)); | |
142 | + g_object_set_data_full(G_OBJECT(dialog),"inputs",inputs,g_free); | |
143 | + debug("Dialog=%p inputs=%p",dialog,inputs); | |
144 | + | |
145 | + GtkGrid * grid = GTK_GRID(gtk_grid_new()); | |
146 | + | |
147 | + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),GTK_WIDGET(grid),TRUE,TRUE,0); | |
148 | + | |
149 | + // https://developer.gnome.org/hig/stable/visual-layout.html.en | |
150 | + gtk_container_set_border_width(GTK_CONTAINER(grid),18); | |
151 | + gtk_grid_set_row_spacing(GTK_GRID(grid),6); | |
152 | + gtk_grid_set_column_spacing(GTK_GRID(grid),12); | |
153 | + | |
154 | + // https://developer.gnome.org/hig/stable/visual-layout.html.en | |
155 | + // gtk_box_set_spacing(GTK_BOX(content_area),18); | |
156 | + | |
157 | + for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) { | |
158 | + | |
159 | + GtkWidget * label = gtk_label_new(gettext(entries[ix].label)); | |
160 | + gtk_label_set_xalign(GTK_LABEL(label),1); | |
161 | + gtk_grid_attach(grid,label,0,ix,1,1); | |
162 | + | |
163 | + inputs[ix] = gtk_entry_new(); | |
164 | + debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]); | |
165 | + | |
166 | + if(entries[ix].default_value) { | |
167 | + gtk_entry_set_text(GTK_ENTRY(inputs[ix]),gettext(entries[ix].default_value)); | |
168 | + } | |
169 | + | |
170 | + gtk_entry_set_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].width); | |
171 | +// gtk_entry_set_max_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].n_chars); | |
172 | + gtk_widget_set_hexpand(inputs[ix],FALSE); | |
173 | + gtk_widget_set_vexpand(inputs[ix],FALSE); | |
174 | + | |
175 | + gtk_grid_attach(grid,inputs[ix],1,ix,entries[ix].width,1); | |
176 | + | |
177 | + } | |
178 | + | |
179 | + g_autofree gchar * filename = g_strdup_printf("%s/" G_STRINGIFY(PRODUCT_NAME) ".desktop",g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP)); | |
180 | + | |
181 | + gtk_entry_set_text(GTK_ENTRY(inputs[0]),filename); | |
182 | + | |
183 | + /* | |
184 | + gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[1]),G_STRINGIFY(PRODUCT_NAME)); | |
185 | + gtk_entry_set_text(GTK_ENTRY(inputs[1]),G_STRINGIFY(PRODUCT_NAME)); | |
186 | + | |
187 | + gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[2]),G_STRINGIFY(PRODUCT_NAME)); | |
188 | + gtk_entry_set_text(GTK_ENTRY(inputs[2]),G_STRINGIFY(PRODUCT_NAME)); | |
189 | + */ | |
190 | + | |
191 | + gtk_entry_set_placeholder_text(GTK_ENTRY(inputs[3]),v3270_get_url(terminal)); | |
192 | + gtk_entry_set_text(GTK_ENTRY(inputs[3]),v3270_get_url(terminal)); | |
193 | + gtk_entry_set_input_hints(GTK_ENTRY(inputs[3]),GTK_INPUT_HINT_SPELLCHECK); | |
194 | + | |
195 | + gtk_widget_show_all(GTK_WIDGET(grid)); | |
196 | + return dialog; | |
197 | + } | |
198 | + | |
199 | + void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal) { | |
200 | + | |
201 | + debug("%s(%d)",__FUNCTION__,response_id); | |
202 | + | |
203 | + if(response_id == GTK_RESPONSE_APPLY) { | |
204 | + | |
205 | + static const char * key_file_data = | |
206 | + "[Desktop Entry]\n" \ | |
207 | + "Icon=" G_STRINGIFY(PRODUCT_NAME) "\n" \ | |
208 | + "Terminal=false\n" \ | |
209 | + "Type=Application\n" \ | |
210 | + "StartupNotify=true\n" \ | |
211 | + "Categories=GTK;GNOME;TerminalEmulator\n" \ | |
212 | + "OnlyShowIn=GNOME;Unity\n"; | |
213 | + | |
214 | + GError * error = NULL; | |
215 | + size_t ix; | |
216 | + | |
217 | + GKeyFile * keyfile = g_key_file_new(); | |
218 | + g_key_file_load_from_data(keyfile,key_file_data,-1,G_KEY_FILE_NONE,NULL); | |
219 | + | |
220 | +#ifdef DEBUG | |
221 | + { | |
222 | + g_autofree gchar * dbg_data = g_key_file_to_data(keyfile,NULL,NULL); | |
223 | + debug("\n%s\n",dbg_data); | |
224 | + } | |
225 | +#endif // DEBUG | |
226 | + | |
227 | + | |
228 | + GtkWidget ** inputs = g_object_get_data(G_OBJECT(dialog),"inputs"); | |
229 | + debug("dialog=%p inputs=%p",dialog,inputs); | |
230 | + | |
231 | + for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) { | |
232 | + if(entries[ix].key) { | |
233 | + debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]); | |
234 | + g_key_file_set_string(keyfile,"Desktop Entry",entries[ix].key,gtk_entry_get_text(GTK_ENTRY(inputs[ix]))); | |
235 | + } | |
236 | + } | |
237 | + | |
238 | + // Get session filename | |
239 | + /* | |
240 | + const gchar * session_file = v3270_get_session_filename(terminal); | |
241 | + | |
242 | + if(!session_file) { | |
243 | + | |
244 | + // No session file, create one. | |
245 | + | |
246 | + // Check for configdir | |
247 | + g_autofree gchar * configdir = g_build_filename(g_get_user_config_dir(),G_STRINGIFY(PRODUCT_NAME),"sessions",NULL); | |
248 | + g_mkdir_with_parents(configdir,0755); | |
249 | + | |
250 | + // Create a base name | |
251 | + g_autofree gchar * basename = g_path_get_basename(gtk_entry_get_text(GTK_ENTRY(inputs[0]))); | |
252 | + | |
253 | + gchar *ptr = strrchr(basename,'.'); | |
254 | + if(ptr) | |
255 | + *ptr = 0; | |
256 | + | |
257 | + ix = time(NULL); | |
258 | + gchar * new_session_file = g_strdup_printf("%s/%s.3270",configdir,basename); | |
259 | + while(!g_file_test(new_session_file,G_FILE_TEST_EXISTS)) { | |
260 | + g_free(new_session_file); | |
261 | + new_session_file = g_strdup_printf("%s/%s_%08lx.3270",configdir,basename,(unsigned long) ix++); | |
262 | + } | |
263 | + | |
264 | + g_message("Saving session to %s",new_session_file); | |
265 | + v3270_set_session_filename(terminal,new_session_file); | |
266 | + g_free(new_session_file); | |
267 | + | |
268 | + } | |
269 | + */ | |
270 | + | |
271 | + // Get program file name | |
272 | + // https://stackoverflow.com/questions/4517425/how-to-get-program-path | |
273 | + { | |
274 | + char buffer[4096]; | |
275 | + g_autofree gchar * pidfile = g_strdup_printf("/proc/%d/exe", getpid()); | |
276 | + | |
277 | + int bytes = readlink(pidfile,buffer,4095); | |
278 | + | |
279 | + if(bytes >= 0) | |
280 | + buffer[bytes] = '\0'; | |
281 | + | |
282 | + g_autofree gchar * exec_line = g_strdup_printf("%s \"%s\"",buffer,v3270_key_file_get_file_name(terminal)); | |
283 | + g_key_file_set_string(keyfile,"Desktop Entry","Exec",exec_line); | |
284 | + | |
285 | + } | |
286 | + | |
287 | + g_key_file_save_to_file(keyfile,gtk_entry_get_text(GTK_ENTRY(inputs[0])),&error); | |
288 | + | |
289 | + if(error) { | |
290 | + | |
291 | + g_message("%s",error->message); | |
292 | + | |
293 | + | |
294 | + g_error_free(error); | |
295 | + | |
296 | + } else { | |
297 | + | |
298 | + g_message("File \"%s\" was saved",gtk_entry_get_text(GTK_ENTRY(inputs[0]))); | |
299 | + | |
300 | + } | |
301 | + | |
302 | + | |
303 | + g_key_file_free(keyfile); | |
304 | + } | |
305 | + | |
306 | + gtk_widget_destroy(dialog); | |
307 | + | |
308 | +} | ... | ... |
... | ... | @@ -0,0 +1,273 @@ |
1 | +/* | |
2 | + * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 | |
3 | + * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a | |
4 | + * aplicativos mainframe. Registro no INPI sob o nome G3270. | |
5 | + * | |
6 | + * Copyright (C) <2008> <Banco do Brasil S.A.> | |
7 | + * | |
8 | + * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob | |
9 | + * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela | |
10 | + * Free Software Foundation. | |
11 | + * | |
12 | + * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER | |
13 | + * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO | |
14 | + * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para | |
15 | + * obter mais detalhes. | |
16 | + * | |
17 | + * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este | |
18 | + * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin | |
19 | + * St, Fifth Floor, Boston, MA 02110-1301 USA | |
20 | + * | |
21 | + * Este programa está nomeado como - e possui - linhas de código. | |
22 | + * | |
23 | + * Contatos: | |
24 | + * | |
25 | + * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) | |
26 | + * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) | |
27 | + * | |
28 | + */ | |
29 | + | |
30 | + /** | |
31 | + * @brief Implement Windows version of the save desktop icon action. | |
32 | + * | |
33 | + * References: | |
34 | + * | |
35 | + * <https://stackoverflow.com/questions/3906974/how-to-programmatically-create-a-shortcut-using-win32> | |
36 | + * <https://docs.microsoft.com/pt-br/windows/win32/shell/links?redirectedfrom=MSDN> | |
37 | + * | |
38 | + */ | |
39 | + | |
40 | +// #include <stdafx.h> | |
41 | + #include <winsock2.h> | |
42 | + #include <windows.h> | |
43 | + #include <winnls.h> | |
44 | + #include <shobjidl.h> | |
45 | + #include <objbase.h> | |
46 | + #include <objidl.h> | |
47 | + #include <shlguid.h> | |
48 | + | |
49 | + #include <v3270.h> | |
50 | + #include <pw3270.h> | |
51 | + #include <pw3270/application.h> | |
52 | + #include <v3270/actions.h> | |
53 | + #include <lib3270.h> | |
54 | + #include <lib3270/log.h> | |
55 | + | |
56 | + static GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal); | |
57 | + static void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal); | |
58 | + | |
59 | + static const struct _entry { | |
60 | + | |
61 | + const gchar * label; | |
62 | + const gchar * tooltip; | |
63 | + gint width; | |
64 | + | |
65 | + } entries[] = { | |
66 | + | |
67 | + { | |
68 | + .label = N_("Launcher name"), | |
69 | + .width = 40, | |
70 | + }, | |
71 | + | |
72 | + { | |
73 | + .label = N_("Description"), | |
74 | + .width = 20, | |
75 | + } | |
76 | + | |
77 | + }; | |
78 | + | |
79 | + GAction * pw3270_action_save_desktop_icon_new(void) { | |
80 | + | |
81 | + V3270SimpleAction * action = v3270_dialog_action_new(factory); | |
82 | + | |
83 | + action->name = "save.launcher"; | |
84 | + action->label = _("Save desktop icon"); | |
85 | + action->tooltip = _("Create a desktop icon for the current session"); | |
86 | + | |
87 | + return G_ACTION(action); | |
88 | + | |
89 | + } | |
90 | + | |
91 | + GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal) { | |
92 | + | |
93 | + size_t ix; | |
94 | + | |
95 | + gboolean use_header; | |
96 | + g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL); | |
97 | + | |
98 | + GtkWidget * dialog = | |
99 | + GTK_WIDGET(g_object_new( | |
100 | + GTK_TYPE_DIALOG, | |
101 | + "use-header-bar", (use_header ? 1 : 0), | |
102 | + NULL | |
103 | + )); | |
104 | + | |
105 | + gtk_window_set_modal(GTK_WINDOW(dialog),TRUE); | |
106 | + gtk_window_set_title(GTK_WINDOW(dialog),action->label); | |
107 | + | |
108 | + gtk_dialog_add_buttons( | |
109 | + GTK_DIALOG(dialog), | |
110 | + _("_Cancel"), GTK_RESPONSE_CANCEL, | |
111 | + _("_Save"), GTK_RESPONSE_APPLY, | |
112 | + NULL | |
113 | + ); | |
114 | + | |
115 | + g_signal_connect(dialog,"response",G_CALLBACK(response),terminal); | |
116 | + | |
117 | + // Create entry fields | |
118 | + GtkWidget ** inputs = g_new0(GtkWidget *,G_N_ELEMENTS(entries)); | |
119 | + g_object_set_data_full(G_OBJECT(dialog),"inputs",inputs,g_free); | |
120 | + debug("Dialog=%p inputs=%p",dialog,inputs); | |
121 | + | |
122 | + GtkGrid * grid = GTK_GRID(gtk_grid_new()); | |
123 | + | |
124 | + gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),GTK_WIDGET(grid),TRUE,TRUE,0); | |
125 | + | |
126 | + // https://developer.gnome.org/hig/stable/visual-layout.html.en | |
127 | + gtk_container_set_border_width(GTK_CONTAINER(grid),18); | |
128 | + gtk_grid_set_row_spacing(GTK_GRID(grid),6); | |
129 | + gtk_grid_set_column_spacing(GTK_GRID(grid),12); | |
130 | + | |
131 | + for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) { | |
132 | + | |
133 | + GtkWidget * label = gtk_label_new(gettext(entries[ix].label)); | |
134 | + gtk_label_set_xalign(GTK_LABEL(label),1); | |
135 | + gtk_grid_attach(grid,label,0,ix,1,1); | |
136 | + | |
137 | + inputs[ix] = gtk_entry_new(); | |
138 | + debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]); | |
139 | + | |
140 | + gtk_entry_set_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].width); | |
141 | + gtk_widget_set_hexpand(inputs[ix],FALSE); | |
142 | + gtk_widget_set_vexpand(inputs[ix],FALSE); | |
143 | + | |
144 | + gtk_grid_attach(grid,inputs[ix],1,ix,entries[ix].width,1); | |
145 | + | |
146 | + } | |
147 | + | |
148 | + { | |
149 | + gchar * filename = g_strdup_printf( | |
150 | + "%s\\" G_STRINGIFY(PRODUCT_NAME) ".lnk", | |
151 | + g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP) | |
152 | + ); | |
153 | + | |
154 | + size_t ix = 0; | |
155 | + | |
156 | + while(g_file_test(filename,G_FILE_TEST_EXISTS)) { | |
157 | + | |
158 | + g_free(filename); | |
159 | + filename = g_strdup_printf( | |
160 | + "%s\\" G_STRINGIFY(PRODUCT_NAME) "%u.lnk", | |
161 | + g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP), | |
162 | + (unsigned int) ++ix | |
163 | + ); | |
164 | + | |
165 | + } | |
166 | + | |
167 | + gtk_entry_set_text(GTK_ENTRY(inputs[0]),filename); | |
168 | + g_free(filename); | |
169 | + } | |
170 | + | |
171 | + gtk_widget_show_all(GTK_WIDGET(grid)); | |
172 | + return dialog; | |
173 | + } | |
174 | + | |
175 | + static HRESULT CreateShortCut(LPSTR pszTargetfile, LPSTR pszTargetargs, LPSTR pszLinkfile, LPSTR pszDescription, int iShowmode, LPSTR pszCurdir, LPSTR pszIconfile, int iIconindex) { | |
176 | + | |
177 | + // https://www.codeproject.com/Articles/11467/How-to-create-short-cuts-link-files | |
178 | + IShellLink* pShellLink; // IShellLink object pointer | |
179 | + IPersistFile* pPersistFile; // IPersistFile object pointer | |
180 | + WORD wszLinkfile[MAX_PATH]; // pszLinkfile as Unicode string | |
181 | + int iWideCharsWritten; // Number of wide characters written | |
182 | + | |
183 | + HRESULT hRes = | |
184 | + CoCreateInstance( | |
185 | + &CLSID_ShellLink, // predefined CLSID of the IShellLink object | |
186 | + NULL, // pointer to parent interface if part of aggregate | |
187 | + CLSCTX_INPROC_SERVER, // caller and called code are in same process | |
188 | + &IID_IShellLink, // predefined interface of the IShellLink object | |
189 | + (void **) &pShellLink); // Returns a pointer to the IShellLink object | |
190 | + | |
191 | + if(!SUCCEEDED(hRes)) { | |
192 | + return hRes; | |
193 | + } | |
194 | + | |
195 | + if(pszTargetfile && strlen(pszTargetfile)) { | |
196 | + hRes = pShellLink->lpVtbl->SetPath(pShellLink,pszTargetfile); | |
197 | + } else { | |
198 | + char filename[MAX_PATH+1]; | |
199 | + memset(filename,0,MAX_PATH+1); | |
200 | + GetModuleFileName(NULL,filename,MAX_PATH); | |
201 | + hRes = pShellLink->lpVtbl->SetPath(pShellLink,filename); | |
202 | + } | |
203 | + | |
204 | + if(pszTargetargs) { | |
205 | + hRes = pShellLink->lpVtbl->SetArguments(pShellLink,pszTargetargs); | |
206 | + } else { | |
207 | + hRes = pShellLink->lpVtbl->SetArguments(pShellLink,""); | |
208 | + } | |
209 | + | |
210 | + if(pszDescription && strlen(pszDescription) > 0) { | |
211 | + hRes = pShellLink->lpVtbl->SetDescription(pShellLink,pszDescription); | |
212 | + } else { | |
213 | + hRes = pShellLink->lpVtbl->SetDescription(pShellLink,_("IBM 3270 Terminal emulator")); | |
214 | + } | |
215 | + | |
216 | + if(iShowmode > 0) { | |
217 | + hRes = pShellLink->lpVtbl->SetShowCmd(pShellLink,iShowmode); | |
218 | + } | |
219 | + | |
220 | + if(pszCurdir && strlen(pszCurdir) > 0) { | |
221 | + hRes = pShellLink->lpVtbl->SetWorkingDirectory(pShellLink,pszCurdir); | |
222 | + } else { | |
223 | + g_autofree gchar * appdir = g_win32_get_package_installation_directory_of_module(NULL); | |
224 | + hRes = pShellLink->lpVtbl->SetWorkingDirectory(pShellLink,appdir); | |
225 | + } | |
226 | + | |
227 | + if(pszIconfile && strlen(pszIconfile) > 0 && iIconindex >= 0) { | |
228 | + hRes = pShellLink->lpVtbl->SetIconLocation(pShellLink, pszIconfile, iIconindex); | |
229 | + } | |
230 | + | |
231 | + // Use the IPersistFile object to save the shell link | |
232 | + hRes = pShellLink->lpVtbl->QueryInterface( | |
233 | + pShellLink, // existing IShellLink object | |
234 | + &IID_IPersistFile, // pre-defined interface of the IPersistFile object | |
235 | + (void **) &pPersistFile); // returns a pointer to the IPersistFile object | |
236 | + | |
237 | + | |
238 | + if(SUCCEEDED(hRes)){ | |
239 | + iWideCharsWritten = MultiByteToWideChar(CP_ACP, 0, pszLinkfile, -1, wszLinkfile, MAX_PATH); | |
240 | + hRes = pPersistFile->lpVtbl->Save(pPersistFile,wszLinkfile, TRUE); | |
241 | + pPersistFile->lpVtbl->Release(pPersistFile); | |
242 | + } | |
243 | + | |
244 | + pShellLink->lpVtbl->Release(pShellLink); | |
245 | + | |
246 | + return hRes; | |
247 | + } | |
248 | + | |
249 | + void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal) { | |
250 | + | |
251 | + debug("%s(%d)",__FUNCTION__,response_id); | |
252 | + | |
253 | + if(response_id == GTK_RESPONSE_APPLY) { | |
254 | + | |
255 | + // Save desktop icon | |
256 | + GtkWidget ** inputs = g_object_get_data(G_OBJECT(dialog),"inputs"); | |
257 | + | |
258 | + HRESULT hRes = CreateShortCut( | |
259 | + NULL, // LPSTR pszTargetfile, | |
260 | + v3270_key_file_get_file_name(terminal), // LPSTR pszTargetargs, | |
261 | + gtk_entry_get_text(GTK_ENTRY(inputs[0])), // LPSTR pszLinkfile, | |
262 | + gtk_entry_get_text(GTK_ENTRY(inputs[1])), //LPSTR pszDescription, | |
263 | + 0, | |
264 | + NULL, | |
265 | + NULL, | |
266 | + 0 | |
267 | + ); | |
268 | + | |
269 | + } | |
270 | + | |
271 | + gtk_widget_destroy(dialog); | |
272 | + | |
273 | +} | ... | ... |
src/objects/windows/savedesktopicon.c
... | ... | @@ -1,273 +0,0 @@ |
1 | -/* | |
2 | - * "Software pw3270, desenvolvido com base nos códigos fontes do WC3270 e X3270 | |
3 | - * (Paul Mattes Paul.Mattes@usa.net), de emulação de terminal 3270 para acesso a | |
4 | - * aplicativos mainframe. Registro no INPI sob o nome G3270. | |
5 | - * | |
6 | - * Copyright (C) <2008> <Banco do Brasil S.A.> | |
7 | - * | |
8 | - * Este programa é software livre. Você pode redistribuí-lo e/ou modificá-lo sob | |
9 | - * os termos da GPL v.2 - Licença Pública Geral GNU, conforme publicado pela | |
10 | - * Free Software Foundation. | |
11 | - * | |
12 | - * Este programa é distribuído na expectativa de ser útil, mas SEM QUALQUER | |
13 | - * GARANTIA; sem mesmo a garantia implícita de COMERCIALIZAÇÃO ou de ADEQUAÇÃO | |
14 | - * A QUALQUER PROPÓSITO EM PARTICULAR. Consulte a Licença Pública Geral GNU para | |
15 | - * obter mais detalhes. | |
16 | - * | |
17 | - * Você deve ter recebido uma cópia da Licença Pública Geral GNU junto com este | |
18 | - * programa; se não, escreva para a Free Software Foundation, Inc., 51 Franklin | |
19 | - * St, Fifth Floor, Boston, MA 02110-1301 USA | |
20 | - * | |
21 | - * Este programa está nomeado como - e possui - linhas de código. | |
22 | - * | |
23 | - * Contatos: | |
24 | - * | |
25 | - * perry.werneck@gmail.com (Alexandre Perry de Souza Werneck) | |
26 | - * erico.mendonca@gmail.com (Erico Mascarenhas Mendonça) | |
27 | - * | |
28 | - */ | |
29 | - | |
30 | - /** | |
31 | - * @brief Implement Windows version of the save desktop icon action. | |
32 | - * | |
33 | - * References: | |
34 | - * | |
35 | - * <https://stackoverflow.com/questions/3906974/how-to-programmatically-create-a-shortcut-using-win32> | |
36 | - * <https://docs.microsoft.com/pt-br/windows/win32/shell/links?redirectedfrom=MSDN> | |
37 | - * | |
38 | - */ | |
39 | - | |
40 | -// #include <stdafx.h> | |
41 | - #include <winsock2.h> | |
42 | - #include <windows.h> | |
43 | - #include <winnls.h> | |
44 | - #include <shobjidl.h> | |
45 | - #include <objbase.h> | |
46 | - #include <objidl.h> | |
47 | - #include <shlguid.h> | |
48 | - | |
49 | - #include <v3270.h> | |
50 | - #include <pw3270.h> | |
51 | - #include <pw3270/application.h> | |
52 | - #include <v3270/actions.h> | |
53 | - #include <lib3270.h> | |
54 | - #include <lib3270/log.h> | |
55 | - | |
56 | - static GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal); | |
57 | - static void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal); | |
58 | - | |
59 | - static const struct _entry { | |
60 | - | |
61 | - const gchar * label; | |
62 | - const gchar * tooltip; | |
63 | - gint width; | |
64 | - | |
65 | - } entries[] = { | |
66 | - | |
67 | - { | |
68 | - .label = N_("Launcher name"), | |
69 | - .width = 40, | |
70 | - }, | |
71 | - | |
72 | - { | |
73 | - .label = N_("Description"), | |
74 | - .width = 20, | |
75 | - } | |
76 | - | |
77 | - }; | |
78 | - | |
79 | - GAction * pw3270_action_save_desktop_icon_new(void) { | |
80 | - | |
81 | - V3270SimpleAction * action = v3270_dialog_action_new(factory); | |
82 | - | |
83 | - action->name = "save.launcher"; | |
84 | - action->label = _("Save desktop icon"); | |
85 | - action->tooltip = _("Create a desktop icon for the current session"); | |
86 | - | |
87 | - return G_ACTION(action); | |
88 | - | |
89 | - } | |
90 | - | |
91 | - GtkWidget * factory(V3270SimpleAction *action, GtkWidget *terminal) { | |
92 | - | |
93 | - size_t ix; | |
94 | - | |
95 | - gboolean use_header; | |
96 | - g_object_get(gtk_settings_get_default(), "gtk-dialogs-use-header", &use_header, NULL); | |
97 | - | |
98 | - GtkWidget * dialog = | |
99 | - GTK_WIDGET(g_object_new( | |
100 | - GTK_TYPE_DIALOG, | |
101 | - "use-header-bar", (use_header ? 1 : 0), | |
102 | - NULL | |
103 | - )); | |
104 | - | |
105 | - gtk_window_set_modal(GTK_WINDOW(dialog),TRUE); | |
106 | - gtk_window_set_title(GTK_WINDOW(dialog),action->label); | |
107 | - | |
108 | - gtk_dialog_add_buttons( | |
109 | - GTK_DIALOG(dialog), | |
110 | - _("_Cancel"), GTK_RESPONSE_CANCEL, | |
111 | - _("_Save"), GTK_RESPONSE_APPLY, | |
112 | - NULL | |
113 | - ); | |
114 | - | |
115 | - g_signal_connect(dialog,"response",G_CALLBACK(response),terminal); | |
116 | - | |
117 | - // Create entry fields | |
118 | - GtkWidget ** inputs = g_new0(GtkWidget *,G_N_ELEMENTS(entries)); | |
119 | - g_object_set_data_full(G_OBJECT(dialog),"inputs",inputs,g_free); | |
120 | - debug("Dialog=%p inputs=%p",dialog,inputs); | |
121 | - | |
122 | - GtkGrid * grid = GTK_GRID(gtk_grid_new()); | |
123 | - | |
124 | - gtk_box_pack_start(GTK_BOX(gtk_dialog_get_content_area(GTK_DIALOG(dialog))),GTK_WIDGET(grid),TRUE,TRUE,0); | |
125 | - | |
126 | - // https://developer.gnome.org/hig/stable/visual-layout.html.en | |
127 | - gtk_container_set_border_width(GTK_CONTAINER(grid),18); | |
128 | - gtk_grid_set_row_spacing(GTK_GRID(grid),6); | |
129 | - gtk_grid_set_column_spacing(GTK_GRID(grid),12); | |
130 | - | |
131 | - for(ix = 0; ix < G_N_ELEMENTS(entries); ix++) { | |
132 | - | |
133 | - GtkWidget * label = gtk_label_new(gettext(entries[ix].label)); | |
134 | - gtk_label_set_xalign(GTK_LABEL(label),1); | |
135 | - gtk_grid_attach(grid,label,0,ix,1,1); | |
136 | - | |
137 | - inputs[ix] = gtk_entry_new(); | |
138 | - debug("inputs[%u]=%p",(unsigned int) ix, inputs[ix]); | |
139 | - | |
140 | - gtk_entry_set_width_chars(GTK_ENTRY(inputs[ix]),entries[ix].width); | |
141 | - gtk_widget_set_hexpand(inputs[ix],FALSE); | |
142 | - gtk_widget_set_vexpand(inputs[ix],FALSE); | |
143 | - | |
144 | - gtk_grid_attach(grid,inputs[ix],1,ix,entries[ix].width,1); | |
145 | - | |
146 | - } | |
147 | - | |
148 | - { | |
149 | - gchar * filename = g_strdup_printf( | |
150 | - "%s\\" G_STRINGIFY(PRODUCT_NAME) ".lnk", | |
151 | - g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP) | |
152 | - ); | |
153 | - | |
154 | - size_t ix = 0; | |
155 | - | |
156 | - while(g_file_test(filename,G_FILE_TEST_EXISTS)) { | |
157 | - | |
158 | - g_free(filename); | |
159 | - filename = g_strdup_printf( | |
160 | - "%s\\" G_STRINGIFY(PRODUCT_NAME) "%u.lnk", | |
161 | - g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP), | |
162 | - (unsigned int) ++ix | |
163 | - ); | |
164 | - | |
165 | - } | |
166 | - | |
167 | - gtk_entry_set_text(GTK_ENTRY(inputs[0]),filename); | |
168 | - g_free(filename); | |
169 | - } | |
170 | - | |
171 | - gtk_widget_show_all(GTK_WIDGET(grid)); | |
172 | - return dialog; | |
173 | - } | |
174 | - | |
175 | - static HRESULT CreateShortCut(LPSTR pszTargetfile, LPSTR pszTargetargs, LPSTR pszLinkfile, LPSTR pszDescription, int iShowmode, LPSTR pszCurdir, LPSTR pszIconfile, int iIconindex) { | |
176 | - | |
177 | - // https://www.codeproject.com/Articles/11467/How-to-create-short-cuts-link-files | |
178 | - IShellLink* pShellLink; // IShellLink object pointer | |
179 | - IPersistFile* pPersistFile; // IPersistFile object pointer | |
180 | - WORD wszLinkfile[MAX_PATH]; // pszLinkfile as Unicode string | |
181 | - int iWideCharsWritten; // Number of wide characters written | |
182 | - | |
183 | - HRESULT hRes = | |
184 | - CoCreateInstance( | |
185 | - &CLSID_ShellLink, // predefined CLSID of the IShellLink object | |
186 | - NULL, // pointer to parent interface if part of aggregate | |
187 | - CLSCTX_INPROC_SERVER, // caller and called code are in same process | |
188 | - &IID_IShellLink, // predefined interface of the IShellLink object | |
189 | - (void **) &pShellLink); // Returns a pointer to the IShellLink object | |
190 | - | |
191 | - if(!SUCCEEDED(hRes)) { | |
192 | - return hRes; | |
193 | - } | |
194 | - | |
195 | - if(pszTargetfile && strlen(pszTargetfile)) { | |
196 | - hRes = pShellLink->lpVtbl->SetPath(pShellLink,pszTargetfile); | |
197 | - } else { | |
198 | - char filename[MAX_PATH+1]; | |
199 | - memset(filename,0,MAX_PATH+1); | |
200 | - GetModuleFileName(NULL,filename,MAX_PATH); | |
201 | - hRes = pShellLink->lpVtbl->SetPath(pShellLink,filename); | |
202 | - } | |
203 | - | |
204 | - if(pszTargetargs) { | |
205 | - hRes = pShellLink->lpVtbl->SetArguments(pShellLink,pszTargetargs); | |
206 | - } else { | |
207 | - hRes = pShellLink->lpVtbl->SetArguments(pShellLink,""); | |
208 | - } | |
209 | - | |
210 | - if(pszDescription && strlen(pszDescription) > 0) { | |
211 | - hRes = pShellLink->lpVtbl->SetDescription(pShellLink,pszDescription); | |
212 | - } else { | |
213 | - hRes = pShellLink->lpVtbl->SetDescription(pShellLink,_("IBM 3270 Terminal emulator")); | |
214 | - } | |
215 | - | |
216 | - if(iShowmode > 0) { | |
217 | - hRes = pShellLink->lpVtbl->SetShowCmd(pShellLink,iShowmode); | |
218 | - } | |
219 | - | |
220 | - if(pszCurdir && strlen(pszCurdir) > 0) { | |
221 | - hRes = pShellLink->lpVtbl->SetWorkingDirectory(pShellLink,pszCurdir); | |
222 | - } else { | |
223 | - g_autofree gchar * appdir = g_win32_get_package_installation_directory_of_module(NULL); | |
224 | - hRes = pShellLink->lpVtbl->SetWorkingDirectory(pShellLink,appdir); | |
225 | - } | |
226 | - | |
227 | - if(pszIconfile && strlen(pszIconfile) > 0 && iIconindex >= 0) { | |
228 | - hRes = pShellLink->lpVtbl->SetIconLocation(pShellLink, pszIconfile, iIconindex); | |
229 | - } | |
230 | - | |
231 | - // Use the IPersistFile object to save the shell link | |
232 | - hRes = pShellLink->lpVtbl->QueryInterface( | |
233 | - pShellLink, // existing IShellLink object | |
234 | - &IID_IPersistFile, // pre-defined interface of the IPersistFile object | |
235 | - (void **) &pPersistFile); // returns a pointer to the IPersistFile object | |
236 | - | |
237 | - | |
238 | - if(SUCCEEDED(hRes)){ | |
239 | - iWideCharsWritten = MultiByteToWideChar(CP_ACP, 0, pszLinkfile, -1, wszLinkfile, MAX_PATH); | |
240 | - hRes = pPersistFile->lpVtbl->Save(pPersistFile,wszLinkfile, TRUE); | |
241 | - pPersistFile->lpVtbl->Release(pPersistFile); | |
242 | - } | |
243 | - | |
244 | - pShellLink->lpVtbl->Release(pShellLink); | |
245 | - | |
246 | - return hRes; | |
247 | - } | |
248 | - | |
249 | - void response(GtkWidget *dialog, gint response_id, GtkWidget *terminal) { | |
250 | - | |
251 | - debug("%s(%d)",__FUNCTION__,response_id); | |
252 | - | |
253 | - if(response_id == GTK_RESPONSE_APPLY) { | |
254 | - | |
255 | - // Save desktop icon | |
256 | - GtkWidget ** inputs = g_object_get_data(G_OBJECT(dialog),"inputs"); | |
257 | - | |
258 | - HRESULT hRes = CreateShortCut( | |
259 | - NULL, // LPSTR pszTargetfile, | |
260 | - v3270_key_file_get_file_name(terminal), // LPSTR pszTargetargs, | |
261 | - gtk_entry_get_text(GTK_ENTRY(inputs[0])), // LPSTR pszLinkfile, | |
262 | - gtk_entry_get_text(GTK_ENTRY(inputs[1])), //LPSTR pszDescription, | |
263 | - 0, | |
264 | - NULL, | |
265 | - NULL, | |
266 | - 0 | |
267 | - ); | |
268 | - | |
269 | - } | |
270 | - | |
271 | - gtk_widget_destroy(dialog); | |
272 | - | |
273 | -} |