Mercurial > geeqie
annotate src/ui_help.c @ 622:54e20abb5c6d
Fix display of collection in overlay info.
Due to markup escaped <i>collection</i> was displayed instead of collection's in italic.
Overlay info syntax was extended to allow the wrapping of displayed data with markup.
General syntax is: %name[:length limit][:extra]%
Extra string uses special character '*' to mark the place of the data to display.
If no '*' is present, then extra string is just appended to data.
Any "\n" is replaced by a newline on display.
Pango mark up is accepted in left and right parts.
If data is empty, nothing will be displayed.
Examples:
"%name:<i>*</i>\n%" -> name is displayed in italics ended with a newline
"%size:\n%" -> size is displayed with a newline at end
"%formatted.ISOSpeedRating:ISO *%" -> prefix iso number with "ISO " (ie. "ISO 100")
"Collection <b>*</b>\n" -> display collection name in bold prefixed by "Collection " and a newline is appended
Collection name formatting was slighly improved by not displaying the .gqv extension.
The default overlay info string was modified to use the new syntax, but older info strings should be
displayed as usual.
author | zas_ |
---|---|
date | Sat, 10 May 2008 21:29:53 +0000 |
parents | 985fdfebd89e |
children | 20495dd4e6e6 |
rev | line source |
---|---|
9 | 1 /* |
2 * (SLIK) SimpLIstic sKin functions | |
3 * (C) 2004 John Ellis | |
475 | 4 * Copyright (C) 2008 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" | |
29 | |
30 | |
31 #define HELP_WINDOW_WIDTH 620 | |
32 #define HELP_WINDOW_HEIGHT 350 | |
33 | |
34 | |
35 /* | |
36 *----------------------------------------------------------------------------- | |
37 * 'help' window | |
38 *----------------------------------------------------------------------------- | |
39 */ | |
40 | |
41 #define SCROLL_MARKNAME "scroll_point" | |
42 | |
43 static void help_window_scroll(GtkWidget *text, const gchar *key) | |
44 { | |
45 gchar *needle; | |
46 GtkTextBuffer *buffer; | |
47 GtkTextIter iter; | |
48 GtkTextIter start, end; | |
49 | |
50 if (!text || !key) return; | |
51 | |
52 needle = g_strdup_printf("[section:%s]", key); | |
53 | |
54 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)); | |
55 gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0); | |
56 | |
57 if (gtk_text_iter_forward_search(&iter, needle, GTK_TEXT_SEARCH_TEXT_ONLY, | |
58 &start, &end, NULL)) | |
59 { | |
60 gint line; | |
61 GtkTextMark *mark; | |
62 | |
63 line = gtk_text_iter_get_line(&start); | |
64 gtk_text_buffer_get_iter_at_line_offset(buffer, &iter, line, 0); | |
65 gtk_text_buffer_place_cursor(buffer, &iter); | |
66 | |
67 #if 0 | |
68 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(text), &iter, 0.0, TRUE, 0, 0); | |
69 #endif | |
70 | |
71 /* apparently only scroll_to_mark works when the textview is not visible yet */ | |
72 | |
73 /* if mark exists, move it instead of creating one for every scroll */ | |
74 mark = gtk_text_buffer_get_mark(buffer, SCROLL_MARKNAME); | |
75 if (mark) | |
76 { | |
77 gtk_text_buffer_move_mark(buffer, mark, &iter); | |
78 } | |
79 else | |
80 { | |
81 mark = gtk_text_buffer_create_mark(buffer, SCROLL_MARKNAME, &iter, FALSE); | |
82 } | |
83 gtk_text_view_scroll_to_mark(GTK_TEXT_VIEW(text), mark, 0.0, TRUE, 0, 0); | |
84 } | |
85 | |
86 g_free(needle); | |
87 } | |
88 | |
89 static void help_window_load_text(GtkWidget *text, const gchar *path) | |
90 { | |
91 gchar *pathl; | |
92 FILE *f; | |
93 gchar s_buf[1024]; | |
94 GtkTextBuffer *buffer; | |
95 GtkTextIter iter; | |
96 GtkTextIter start, end; | |
97 | |
98 if (!text || !path) return; | |
99 | |
100 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)); | |
101 | |
102 gtk_text_buffer_get_bounds(buffer, &start, &end); | |
103 gtk_text_buffer_delete(buffer, &start, &end); | |
104 | |
105 gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0); | |
106 | |
107 pathl = path_from_utf8(path); | |
108 f = fopen(pathl, "r"); | |
109 g_free(pathl); | |
110 if (!f) | |
111 { | |
112 gchar *buf; | |
113 buf = g_strdup_printf(_("Unable to load:\n%s"), path); | |
114 gtk_text_buffer_insert(buffer, &iter, buf, -1); | |
115 g_free(buf); | |
116 } | |
117 else | |
118 { | |
119 while (fgets(s_buf, sizeof(s_buf), f)) | |
120 { | |
121 gchar *buf; | |
122 gint l; | |
123 | |
124 l = strlen(s_buf); | |
125 | |
126 if (!g_utf8_validate(s_buf, l, NULL)) | |
127 { | |
128 buf = g_locale_to_utf8(s_buf, strlen(s_buf), NULL, NULL, NULL); | |
129 if (!buf) buf = g_strdup("\n"); | |
130 } | |
131 else | |
132 { | |
133 buf = NULL; | |
134 } | |
135 gtk_text_buffer_insert_with_tags_by_name(buffer, &iter, | |
136 (buf) ? buf : s_buf, -1, | |
137 "monospace", NULL); | |
138 g_free(buf); | |
139 } | |
140 fclose(f); | |
141 } | |
142 | |
143 gtk_text_buffer_get_iter_at_offset(buffer, &iter, 0); | |
144 gtk_text_buffer_place_cursor(buffer, &iter); | |
145 gtk_text_view_scroll_to_iter(GTK_TEXT_VIEW(text), &iter, 0.0, TRUE, 0, 0); | |
146 } | |
147 | |
148 static gint help_window_delete_cb(GtkWidget *widget, GdkEventAny *event, gpointer data) | |
149 { | |
150 gtk_widget_destroy(widget); | |
151 return TRUE; | |
152 } | |
153 | |
154 static void help_window_close(GtkWidget *widget, gpointer data) | |
155 { | |
156 GtkWidget *window = data; | |
157 gtk_widget_destroy(window); | |
158 } | |
159 | |
160 void help_window_set_key(GtkWidget *window, const gchar *key) | |
161 { | |
162 GtkWidget *text; | |
163 | |
164 if (!window) return; | |
165 | |
166 text = g_object_get_data(G_OBJECT(window), "text_widget"); | |
167 if (!text) return; | |
168 | |
169 gdk_window_raise(window->window); | |
170 | |
171 if (key) help_window_scroll(text, key); | |
172 } | |
173 | |
174 void help_window_set_file(GtkWidget *window, const gchar *path, const gchar *key) | |
175 { | |
176 GtkWidget *text; | |
177 | |
178 if (!window || !path) return; | |
179 | |
180 text = g_object_get_data(G_OBJECT(window), "text_widget"); | |
181 if (!text) return; | |
182 | |
183 gdk_window_raise(window->window); | |
184 | |
185 help_window_load_text(text, path); | |
186 help_window_scroll(text, key); | |
187 } | |
188 | |
189 GtkWidget *help_window_new(const gchar *title, | |
190 const gchar *wmclass, const gchar *subclass, | |
191 const gchar *path, const gchar *key) | |
192 { | |
193 GtkWidget *window; | |
194 GtkWidget *text; | |
195 GtkTextBuffer *buffer; | |
196 GtkWidget *vbox; | |
197 GtkWidget *hbox; | |
198 GtkWidget *button; | |
199 GtkWidget *scrolled; | |
200 | |
201 /* window */ | |
202 | |
289 | 203 window = window_new(GTK_WINDOW_TOPLEVEL, subclass, NULL, NULL, title); |
9 | 204 gtk_window_set_resizable(GTK_WINDOW(window), TRUE); |
205 #if 0 | |
206 gtk_container_set_border_width(GTK_CONTAINER(window), PREF_PAD_BORDER); | |
207 #endif | |
208 gtk_window_set_default_size(GTK_WINDOW(window), HELP_WINDOW_WIDTH, HELP_WINDOW_HEIGHT); | |
209 | |
210 g_signal_connect(G_OBJECT(window), "delete_event", | |
211 G_CALLBACK(help_window_delete_cb), NULL); | |
212 | |
213 vbox = gtk_vbox_new(FALSE, 0); | |
214 gtk_container_add(GTK_CONTAINER(window), vbox); | |
215 gtk_widget_show(vbox); | |
216 | |
217 g_object_set_data(G_OBJECT(window), "text_vbox", vbox); | |
218 | |
219 /* text window */ | |
220 | |
221 hbox = gtk_hbox_new(FALSE, 0); | |
222 gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, TRUE, 0); | |
223 gtk_widget_show(hbox); | |
224 | |
225 scrolled = gtk_scrolled_window_new(NULL, NULL); | |
226 gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_IN); | |
227 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), | |
228 GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC); | |
229 gtk_box_pack_start(GTK_BOX(hbox), scrolled, TRUE, TRUE, 0); | |
230 gtk_widget_show(scrolled); | |
231 | |
232 text = gtk_text_view_new(); | |
233 gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE); | |
234 gtk_container_add(GTK_CONTAINER(scrolled), text); | |
235 gtk_widget_show(text); | |
236 | |
237 buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(text)); | |
238 gtk_text_buffer_create_tag(buffer, "monospace", | |
239 "family", "monospace", NULL); | |
240 | |
241 hbox = gtk_hbutton_box_new(); | |
242 gtk_container_set_border_width(GTK_CONTAINER(hbox), PREF_PAD_BORDER); | |
243 gtk_button_box_set_layout(GTK_BUTTON_BOX(hbox), GTK_BUTTONBOX_END); | |
244 gtk_box_pack_end(GTK_BOX(vbox), hbox, FALSE, FALSE, 0); | |
245 gtk_widget_show(hbox); | |
246 | |
247 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
|
248 g_signal_connect(G_OBJECT(button), "clicked", |
9 | 249 G_CALLBACK(help_window_close), window); |
250 gtk_container_add(GTK_CONTAINER(hbox), button); | |
251 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT); | |
252 gtk_widget_grab_default(button); | |
253 gtk_widget_show(button); | |
254 | |
255 g_object_set_data(G_OBJECT(window), "text_widget", text); | |
256 | |
257 help_window_load_text(text, path); | |
258 | |
259 gtk_widget_show(window); | |
260 | |
261 help_window_scroll(text, key); | |
262 | |
263 return window; | |
264 } | |
265 | |
266 GtkWidget *help_window_get_box(GtkWidget *window) | |
267 { | |
268 return g_object_get_data(G_OBJECT(window), "text_vbox"); | |
269 } |