Mercurial > geeqie
annotate src/ui_help.c @ 1777:56c019ed8746
Some systems do not have SA_SIGINFO (siginfo_t), like GNU/Hurd, so just test if defined or not. Patch by Michal iha (Bug ID: 2894271).
author | zas_ |
---|---|
date | Fri, 04 Dec 2009 21:01:11 +0000 |
parents | 89dedc61b1bd |
children | 956aab097ea7 |
rev | line source |
---|---|
9 | 1 /* |
2 * (SLIK) SimpLIstic sKin functions | |
3 * (C) 2004 John Ellis | |
1284 | 4 * Copyright (C) 2008 - 2009 The Geeqie Team |
9 | 5 * |
6 * Author: John Ellis | |
7 * | |
8 * This software is released under the GNU General Public License (GNU GPL). | |
9 * Please read the included file COPYING for more information. | |
10 * This software comes with no warranty of any kind, use at your own risk! | |
11 */ | |
12 | |
13 #ifdef HAVE_CONFIG_H | |
14 # include "config.h" | |
15 #endif | |
16 #include "intl.h" | |
17 | |
18 #include <stdio.h> | |
19 #include <stdlib.h> | |
20 #include <string.h> | |
21 | |
22 #include <gtk/gtk.h> | |
23 | |
289 | 24 #include "main.h" |
9 | 25 #include "ui_help.h" |
26 | |
27 #include "ui_fileops.h" | |
28 #include "ui_misc.h" | |
648
e34c1002e553
Move some functions from main.[ch] to new window.[ch].
zas_
parents:
627
diff
changeset
|
29 #include "window.h" |
9 | 30 |
31 | |
626 | 32 #define HELP_WINDOW_WIDTH 650 |
9 | 33 #define HELP_WINDOW_HEIGHT 350 |
34 | |
35 | |
36 /* | |
37 *----------------------------------------------------------------------------- | |
38 * 'help' window | |
39 *----------------------------------------------------------------------------- | |
40 */ | |
41 | |
42 #define SCROLL_MARKNAME "scroll_point" | |
43 | |
44 static void help_window_scroll(GtkWidget *text, const gchar *key) | |
45 { | |
46 gchar *needle; | |
47 GtkTextBuffer *buffer; | |
48 GtkTextIter iter; | |
49 GtkTextIter start, end; | |
50 | |
51 if (!text || !key) return; | |
52 | |
53 needle = g_strdup_printf("[section:%s]", key); | |
54 | |
55 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)); | |
56 gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0); | |
57 | |
58 if (gtk_text_iter_forward_search(&iter, needle, GTK_TEXT_SEARCH_TEXT_ONLY, | |
59 &start, &end, NULL)) | |
60 { | |
61 gint line; | |
62 GtkTextMark *mark; | |
63 | |
64 line = gtk_text_iter_get_line(&start); | |
65 gtk_text_buffer_get_iter_at_line_offset(buffer, &iter, line, 0); | |
66 gtk_text_buffer_place_cursor(buffer, &iter); | |
67 | |
68 #if 0 | |
69 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(text), &iter, 0.0, TRUE, 0, 0); | |
70 #endif | |
71 | |
72 /* apparently only scroll_to_mark works when the textview is not visible yet */ | |
73 | |
74 /* if mark exists, move it instead of creating one for every scroll */ | |
75 mark = gtk_text_buffer_get_mark(buffer, SCROLL_MARKNAME); | |
76 if (mark) | |
77 { | |
78 gtk_text_buffer_move_mark(buffer, mark, &iter); | |
79 } | |
80 else | |
81 { | |
82 mark = gtk_text_buffer_create_mark(buffer, SCROLL_MARKNAME, &iter, FALSE); | |
83 } | |
84 gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(text), mark, 0.0, TRUE, 0, 0); | |
85 } | |
86 | |
87 g_free(needle); | |
88 } | |
89 | |
90 static void help_window_load_text(GtkWidget *text, const gchar *path) | |
91 { | |
92 gchar *pathl; | |
93 FILE *f; | |
94 gchar s_buf[1024]; | |
95 GtkTextBuffer *buffer; | |
96 GtkTextIter iter; | |
97 GtkTextIter start, end; | |
98 | |
99 if (!text || !path) return; | |
100 | |
101 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)); | |
102 | |
103 gtk_text_buffer_get_bounds(buffer, &start, &end); | |
104 gtk_text_buffer_delete(buffer, &start, &end); | |
105 | |
106 gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0); | |
107 | |
108 pathl = path_from_utf8(path); | |
109 f = fopen(pathl, "r"); | |
110 g_free(pathl); | |
111 if (!f) | |
112 { | |
113 gchar *buf; | |
114 buf = g_strdup_printf(_("Unable to load:\n%s"), path); | |
115 gtk_text_buffer_insert(buffer, &iter, buf, -1); | |
116 g_free(buf); | |
117 } | |
118 else | |
119 { | |
120 while (fgets(s_buf, sizeof(s_buf), f)) | |
121 { | |
122 gchar *buf; | |
123 gint l; | |
124 | |
125 l = strlen(s_buf); | |
126 | |
127 if (!g_utf8_validate(s_buf, l, NULL)) | |
128 { | |
627 | 129 buf = g_locale_to_utf8(s_buf, l, NULL, NULL, NULL); |
9 | 130 if (!buf) buf = g_strdup("\n"); |
131 } | |
132 else | |
133 { | |
134 buf = NULL; | |
135 } | |
136 gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, | |
137 (buf) ? buf : s_buf, -1, | |
138 "monospace", NULL); | |
139 g_free(buf); | |
140 } | |
141 fclose(f); | |
142 } | |
143 | |
144 gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0); | |
145 gtk_text_buffer_place_cursor(buffer, &iter); | |
146 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(text), &iter, 0.0, TRUE, 0, 0); | |
147 } | |
148 | |
1448 | 149 static gboolean help_window_delete_cb(GtkWidget *widget, GdkEventAny *event, gpointer data) |
9 | 150 { |
151 gtk_widget_destroy(widget); | |
152 return TRUE; | |
153 } | |
154 | |
155 static void help_window_close(GtkWidget *widget, gpointer data) | |
156 { | |
157 GtkWidget *window = data; | |
158 gtk_widget_destroy(window); | |
159 } | |
160 | |
161 void help_window_set_key(GtkWidget *window, const gchar *key) | |
162 { | |
163 GtkWidget *text; | |
164 | |
165 if (!window) return; | |
166 | |
167 text = g_object_get_data(G_OBJECT(window), "text_widget"); | |
168 if (!text) return; | |
169 | |
170 gdk_window_raise(window->window); | |
171 | |
172 if (key) help_window_scroll(text, key); | |
173 } | |
174 | |
175 void help_window_set_file(GtkWidget *window, const gchar *path, const gchar *key) | |
176 { | |
177 GtkWidget *text; | |
178 | |
179 if (!window || !path) return; | |
180 | |
181 text = g_object_get_data(G_OBJECT(window), "text_widget"); | |
182 if (!text) return; | |
183 | |
184 gdk_window_raise(window->window); | |
185 | |
186 help_window_load_text(text, path); | |
187 help_window_scroll(text, key); | |
188 } | |
189 | |
190 GtkWidget *help_window_new(const gchar *title, | |
1174
0bea79d87065
Drop useless wmclass stuff. Gtk will take care of it and as said in the documentation using gtk_window_set_wmclass() is sort of pointless.
zas_
parents:
1055
diff
changeset
|
191 const gchar *subclass, |
9 | 192 const gchar *path, const gchar *key) |
193 { | |
194 GtkWidget *window; | |
195 GtkWidget *text; | |
196 GtkTextBuffer *buffer; | |
197 GtkWidget *vbox; | |
198 GtkWidget *hbox; | |
199 GtkWidget *button; | |
200 GtkWidget *scrolled; | |
201 | |
202 /* window */ | |
203 | |
289 | 204 window = window_new(GTK_WINDOW_TOPLEVEL, subclass, NULL, NULL, title); |
9 | 205 gtk_window_set_resizable(GTK_WINDOW(window), TRUE); |
206 #if 0 | |
207 gtk_container_set_border_width(GTK_CONTAINER(window), PREF_PAD_BORDER); | |
208 #endif | |
209 gtk_window_set_default_size(GTK_WINDOW(window), HELP_WINDOW_WIDTH, HELP_WINDOW_HEIGHT); | |
210 | |
211 g_signal_connect(G_OBJECT(window), "delete_event", | |
212 G_CALLBACK(help_window_delete_cb), NULL); | |
213 | |
214 vbox = gtk_vbox_new(FALSE, 0); | |
215 gtk_container_add(GTK_CONTAINER(window), vbox); | |
216 gtk_widget_show(vbox); | |
217 | |
218 g_object_set_data(G_OBJECT(window), "text_vbox", vbox); | |
219 | |
220 /* text window */ | |
221 | |
222 hbox = gtk_hbox_new(FALSE, 0); | |
223 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); | |
224 gtk_widget_show(hbox); | |
225 | |
226 scrolled = gtk_scrolled_window_new(NULL, NULL); | |
227 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN); | |
228 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), | |
229 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
230 gtk_box_pack_start(GTK_BOX(hbox), scrolled, TRUE, TRUE, 0); | |
231 gtk_widget_show(scrolled); | |
232 | |
233 text = gtk_text_view_new(); | |
234 gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE); | |
235 gtk_container_add(GTK_CONTAINER(scrolled), text); | |
236 gtk_widget_show(text); | |
237 | |
238 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)); | |
239 gtk_text_buffer_create_tag(buffer, "monospace", | |
240 "family", "monospace", NULL); | |
241 | |
242 hbox = gtk_hbutton_box_new(); | |
243 gtk_container_set_border_width(GTK_CONTAINER(hbox), PREF_PAD_BORDER); | |
244 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END); | |
245 gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
246 gtk_widget_show(hbox); | |
247 | |
248 button = gtk_button_new_from_stock(GTK_STOCK_CLOSE); | |
513
985fdfebd89e
Remove whitespace between function name and first parenthesis for the sake of consistency. (pass 2)
zas_
parents:
475
diff
changeset
|
249 g_signal_connect(G_OBJECT(button), "clicked", |
9 | 250 G_CALLBACK(help_window_close), window); |
251 gtk_container_add(GTK_CONTAINER(hbox), button); | |
252 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); | |
253 gtk_widget_grab_default(button); | |
254 gtk_widget_show(button); | |
255 | |
256 g_object_set_data(G_OBJECT(window), "text_widget", text); | |
257 | |
258 help_window_load_text(text, path); | |
259 | |
260 gtk_widget_show(window); | |
261 | |
262 help_window_scroll(text, key); | |
263 | |
264 return window; | |
265 } | |
266 | |
267 GtkWidget *help_window_get_box(GtkWidget *window) | |
268 { | |
269 return g_object_get_data(G_OBJECT(window), "text_vbox"); | |
270 } | |
1055
1646720364cf
Adding a vim modeline to all files - patch by Klaus Ethgen
nadvornik
parents:
648
diff
changeset
|
271 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */ |