1 /*
2 LibRCC UI - GTK library
3
4 Copyright (C) 2005-2008 Suren A. Chilingaryan <csa@dside.dyndns.org>
5
6 This library is free software; you can redistribute it and/or modify it
7 under the terms of the GNU Lesser General Public License version 2.1 or later
8 as published by the Free Software Foundation.
9
10 This library is distributed in the hope that it will be useful, but WITHOUT
11 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
13 for more details.
14
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software Foundation, Inc.,
17 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include <stdio.h>
21 #include <gtk/gtk.h>
22
23 #include <librcc.h>
24
25 #include "internal.h"
26 #include "rccnames.h"
27
28 #define TITLE_WIDTH 224
29 #define TITLE_HEIGHT 10
30 #define BOX_SPACING 1
31 #define BOX_BORDER 0
32 #define FRAME_SPACING 1
33 #define FRAME_BORDER 0
34 #define PAGE_SPACING 1
35
36 #if GTK_MAJOR_VERSION > 2
37 # define gtk_container_border_width gtk_container_set_border_width
38 # define gtk_widget_set_usize gtk_widget_set_size_request
39 # define gtk_container_children gtk_container_get_children
40 #endif /* GTK_MAJOR_VERSION */
41
42
rccUiCreateInternal(rcc_ui_context ctx)43 rcc_ui_internal rccUiCreateInternal(rcc_ui_context ctx) {
44 return NULL;
45 }
46
rccUiFreeInternal(rcc_ui_context ctx)47 void rccUiFreeInternal(rcc_ui_context ctx) {
48 }
49
rccUiMenuCreateWidget(rcc_ui_menu_context ctx)50 rcc_ui_widget rccUiMenuCreateWidget(rcc_ui_menu_context ctx) {
51 return NULL;
52 }
53
rccUiMenuFreeWidget(rcc_ui_menu_context ctx)54 void rccUiMenuFreeWidget(rcc_ui_menu_context ctx) {
55 }
56
rccUiMenuGet(rcc_ui_menu_context ctx)57 rcc_ui_id rccUiMenuGet(rcc_ui_menu_context ctx) {
58 #if GTK_MAJOR_VERSION < 3
59 GtkWidget *menu;
60 #endif /* GTK_MAJOR_VERSION */
61
62 if (!ctx) return (rcc_ui_id)-1;
63
64 if (ctx->type == RCC_UI_MENU_OPTION) {
65 switch (rccUiMenuGetRangeType(ctx)) {
66
67 case RCC_OPTION_RANGE_TYPE_BOOLEAN:
68 return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(ctx->widget));
69 case RCC_OPTION_RANGE_TYPE_MENU:
70 break;
71 case RCC_OPTION_RANGE_TYPE_RANGE:
72 return gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ctx->widget));
73 default:
74 return (rcc_ui_id)-1;
75 }
76 }
77
78 #if GTK_MAJOR_VERSION > 2
79 return gtk_combo_box_get_active(GTK_COMBO_BOX(ctx->widget));
80 #else /* GTK_MAJOR_VERSION < 3 */
81 menu = gtk_option_menu_get_menu(ctx->widget);
82 return g_list_index(GTK_MENU_SHELL(menu)->children, gtk_menu_get_active(GTK_MENU(menu)));
83 #endif /* GTK_MAJOR_VERSION */
84 }
85
rccUiMenuSet(rcc_ui_menu_context ctx,rcc_ui_id id)86 int rccUiMenuSet(rcc_ui_menu_context ctx, rcc_ui_id id) {
87 if (!ctx) return -1;
88
89 switch (ctx->type) {
90 case RCC_UI_MENU_OPTION:
91 switch (rccUiMenuGetRangeType(ctx)) {
92 case RCC_OPTION_RANGE_TYPE_BOOLEAN:
93 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ctx->widget),id);
94 break;
95 case RCC_OPTION_RANGE_TYPE_MENU:
96 #if GTK_MAJOR_VERSION > 2
97 gtk_combo_box_set_active(GTK_COMBO_BOX(ctx->widget), id);
98 #else /* GTK_MAJOR_VERSION < 3 */
99 gtk_option_menu_set_history(ctx->widget, id);
100 #endif /* GTK_MAJOR_VERSION */
101 break;
102 case RCC_OPTION_RANGE_TYPE_RANGE:
103 gtk_spin_button_set_value(GTK_SPIN_BUTTON(ctx->widget), id);
104 default:
105 return -1;
106 }
107 break;
108 default:
109 #if GTK_MAJOR_VERSION > 2
110 gtk_combo_box_set_active(GTK_COMBO_BOX(ctx->widget), id);
111 #else /* GTK_MAJOR_VERSION < 3 */
112 gtk_option_menu_set_history(ctx->widget, id);
113 #endif /* GTK_MAJOR_VERSION */
114 }
115
116 return 0;
117 }
118
119
rccGtkMenuLanguageCB(GtkWidget * w,gpointer item)120 static void rccGtkMenuLanguageCB(GtkWidget * w, gpointer item) {
121 rccUiRestoreLanguage(((rcc_ui_menu_context)item)->uictx);
122 }
123
rccUiMenuConfigureWidget(rcc_ui_menu_context ctx)124 int rccUiMenuConfigureWidget(rcc_ui_menu_context ctx) {
125 unsigned int i;
126 unsigned long num;
127
128 rcc_context rccctx;
129 rcc_ui_context uictx;
130
131 rcc_language_config config;
132 rcc_language_id language_id;
133
134 rcc_class_id class_id;
135 rcc_charset_id charset_id;
136 rcc_engine_id engine_id;
137 gint value_id = 0;
138
139 const char *language;
140 const char *charset;
141 const char *engine;
142
143 rcc_option_range *range;
144 rcc_option_name *option_name;
145 rcc_option_value_names optnames;
146
147 GtkWidget *menu = NULL;
148 GtkWidget *item;
149 #if GTK_MAJOR_VERSION > 2
150 GtkCellRenderer *cell = NULL;
151 GtkTreeStore *store = NULL;
152 GtkTreeIter iter;
153 GtkAdjustment *adjustment;
154 #else /* GTK_MAJOR_VERSION < 3 */
155 GtkWidget *list = NULL;
156 GtkObject *adjustment;
157 #endif /* GTK_MAJOR_VERSION */
158
159 if (!ctx) return -1;
160
161 uictx = ctx->uictx;
162 rccctx = uictx->rccctx;
163
164 switch (ctx->type) {
165 case RCC_UI_MENU_LANGUAGE:
166 #if GTK_MAJOR_VERSION < 3
167 case RCC_UI_MENU_CHARSET:
168 #endif /* GTK_MAJOR_VERSION */
169 case RCC_UI_MENU_ENGINE:
170 if (ctx->widget) menu = ctx->widget;
171 else
172 #if GTK_MAJOR_VERSION > 2
173 menu = gtk_combo_box_text_new();
174 gtk_combo_box_text_remove_all(GTK_COMBO_BOX_TEXT(menu));
175 #else /* GTK_MAJOR_VERSION < 3 */
176 menu = gtk_option_menu_new();
177 gtk_option_menu_remove_menu(GTK_OPTION_MENU(menu));
178 list = gtk_menu_new();
179 #endif /* GTK_MAJOR_VERSION */
180
181 ctx->widget = menu;
182 break;
183 default:
184 ;
185 }
186
187 #if GTK_MAJOR_VERSION > 2
188 switch (ctx->type) {
189 case RCC_UI_MENU_CHARSET:
190 if (ctx->widget) {
191 menu = ctx->widget;
192 store = GTK_TREE_STORE(gtk_combo_box_get_model(GTK_COMBO_BOX(menu)));
193 gtk_tree_store_clear(store);
194 } else {
195 store = gtk_tree_store_new(2, G_TYPE_STRING, G_TYPE_BOOLEAN);
196 menu = gtk_combo_box_new_with_model(GTK_TREE_MODEL(store));
197 g_object_unref (store);
198
199 cell = gtk_cell_renderer_text_new();
200 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(menu), cell, TRUE);
201 gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT(menu), cell, "text", 0, "sensitive", 1, NULL);
202
203 ctx->widget = menu;
204 }
205 break;
206 default:
207 ;
208 }
209 #endif /* GTK_MAJOR_VERSION */
210
211 switch (ctx->type) {
212 case RCC_UI_MENU_LANGUAGE:
213 num = rccGetLanguageNumber(rccctx);
214
215 for (i=0; i<(num?num:1); i++) {
216 language = rccUiGetLanguageName(uictx, (rcc_language_id)i);
217 if (!language) continue;
218
219 #if GTK_MAJOR_VERSION > 2
220 gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(menu), NULL, language);
221 #else /* GTK_MAJOR_VERSION < 3 */
222 item = gtk_menu_item_new_with_label(language);
223 gtk_widget_show(item);
224 gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(rccGtkMenuLanguageCB), ctx);
225 gtk_menu_append(GTK_MENU(list), item);
226 #endif /* GTK_MAJOR_VERSION */
227 }
228
229 language_id = rccGetSelectedLanguage(rccctx);
230 if (language_id == (rcc_language_id)-1) language_id = 0;
231
232 value_id = language_id;
233 break;
234 case RCC_UI_MENU_CHARSET:
235 language_id = (rcc_language_id)rccUiMenuGet(uictx->language);
236 class_id = rccUiMenuGetClassId(ctx);
237 config = rccGetConfig(rccctx, language_id);
238 num = rccConfigGetClassCharsetNumber(config, class_id);
239
240 for (i=0;i<(num?num:1);i++) {
241 charset = rccUiGetCharsetName(uictx, language_id, class_id, (rcc_charset_id)i);
242 if (!charset) continue;
243
244 #if GTK_MAJOR_VERSION > 2
245 gtk_tree_store_append(store, &iter, NULL);
246 gtk_tree_store_set(store, &iter, 0, charset, 1, !rccIsDisabledCharsetName(rccctx, class_id, charset), -1);
247 #else /* GTK_MAJOR_VERSION < 3 */
248 item = gtk_menu_item_new_with_label(charset);
249 if (rccIsDisabledCharsetName(rccctx, class_id, charset))
250 gtk_widget_set_sensitive(item, 0);
251 else
252 gtk_widget_show(item);
253 gtk_menu_append(GTK_MENU(list), item);
254 #endif /* GTK_MAJOR_VERSION */
255 }
256
257
258 charset_id = rccConfigGetSelectedCharset(config, class_id);
259 if (charset_id == (rcc_charset_id)-1) charset_id = 0;
260 value_id = charset_id;
261 break;
262 case RCC_UI_MENU_ENGINE:
263 language_id = (rcc_language_id)rccUiMenuGet(uictx->language);
264 config = rccGetConfig(rccctx, language_id);
265 num = rccConfigGetEngineNumber(config);
266
267 for (i=0;i<(num?num:1);i++) {
268 engine = rccUiGetEngineName(uictx, language_id, (rcc_engine_id)i);
269 if (!engine) continue;
270
271 #if GTK_MAJOR_VERSION > 2
272 gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(menu), NULL, engine);
273 #else /* GTK_MAJOR_VERSION < 3 */
274 item = gtk_menu_item_new_with_label(engine);
275 gtk_widget_show(item);
276 gtk_menu_append(GTK_MENU(list), item);
277 #endif /* GTK_MAJOR_VERSION */
278 }
279
280 engine_id = rccConfigGetCurrentEngine(config);
281 if (engine_id == (rcc_engine_id)-1) engine_id = 0;
282 value_id = engine_id;
283 break;
284 case RCC_UI_MENU_OPTION:
285 switch (rccUiMenuGetRangeType(ctx)) {
286 case RCC_OPTION_RANGE_TYPE_BOOLEAN:
287 if (!ctx->widget) {
288 item = gtk_check_button_new_with_label(rccUiGetOptionName(uictx, rccUiMenuGetOption(ctx)));
289 ctx->widget = item;
290 }
291 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(ctx->widget), rccGetOption(rccctx, rccUiMenuGetOption(ctx)));
292 break;
293 case RCC_OPTION_RANGE_TYPE_MENU:
294 if (!ctx->widget) {
295 option_name = rccUiGetOptionRccName(uictx, rccUiMenuGetOption(ctx));
296 if (!option_name) return -1;
297 optnames = option_name->value_names;
298 if (!optnames) return -1;
299
300 #if GTK_MAJOR_VERSION > 2
301 menu = gtk_combo_box_text_new();
302 for (i=0;optnames[i];i++) {
303 gtk_combo_box_text_append(GTK_COMBO_BOX_TEXT(menu), NULL, optnames[i]);
304 }
305 #else /* GTK_MAJOR_VERSION < 3 */
306 list = gtk_menu_new();
307 for (i=0;optnames[i];i++) {
308 item = gtk_menu_item_new_with_label(optnames[i]);
309 gtk_widget_show(item);
310 gtk_menu_append(GTK_MENU(list), item);
311 }
312
313 menu = gtk_option_menu_new();
314
315 gtk_option_menu_remove_menu(GTK_OPTION_MENU(menu));
316 gtk_option_menu_set_menu(GTK_OPTION_MENU(menu), list);
317 #endif /* GTK_MAJOR_VERSION */
318
319 ctx->widget = menu;
320 }
321 #if GTK_MAJOR_VERSION > 2
322 gtk_combo_box_set_active(GTK_COMBO_BOX(ctx->widget), rccGetOption(rccctx, rccUiMenuGetOption(ctx)));
323 #else /* GTK_MAJOR_VERSION < 3 */
324 gtk_option_menu_set_history(GTK_OPTION_MENU(ctx->widget), rccGetOption(rccctx, rccUiMenuGetOption(ctx)));
325 #endif /* GTK_MAJOR_VERSION */
326 break;
327 case RCC_OPTION_RANGE_TYPE_RANGE:
328 range = rccUiMenuGetRange(ctx);
329 adjustment = gtk_adjustment_new(rccGetOption(rccctx, rccUiMenuGetOption(ctx)), range->min, range->max, range->step, 0, 0);
330 /* item = gtk_hscale_new(GTK_ADJUSTMENT(adjustment));
331 gtk_scale_set_digits(GTK_SCALE(item), 0);*/
332 item = gtk_spin_button_new(GTK_ADJUSTMENT(adjustment), range->step, 0);
333 ctx->widget = item;
334 break;
335 default:
336 return -1;
337 }
338 break;
339 default:
340 return -1;
341 }
342
343
344 switch (ctx->type) {
345 case RCC_UI_MENU_LANGUAGE:
346 #if GTK_MAJOR_VERSION > 2
347 g_signal_connect(G_OBJECT(menu), "changed", G_CALLBACK(rccGtkMenuLanguageCB), ctx);
348 #endif /* GTK_MAJOR_VERSION */
349
350 case RCC_UI_MENU_CHARSET:
351 case RCC_UI_MENU_ENGINE:
352 #if GTK_MAJOR_VERSION > 2
353 gtk_combo_box_set_active(GTK_COMBO_BOX(menu), value_id);
354 #else /* GTK_MAJOR_VERSION < 3 */
355 gtk_option_menu_set_menu(GTK_OPTION_MENU(menu), list);
356 gtk_option_menu_set_history(GTK_OPTION_MENU(menu), value_id);
357 #endif /* GTK_MAJOR_VERSION */
358
359 break;
360 default:
361 ;
362 }
363
364 return 0;
365 }
366
rccUiBoxCreate(rcc_ui_menu_context ctx,const char * title)367 rcc_ui_box rccUiBoxCreate(rcc_ui_menu_context ctx, const char *title) {
368 GtkWidget *hbox, *label;
369 #if GTK_MAJOR_VERSION > 2
370 hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, BOX_SPACING);
371 #else /* GTK_MAJOR_VERSION < 3 */
372 hbox = gtk_hbox_new(FALSE, BOX_SPACING);
373 #endif /* GTK_MAJOR_VERSION */
374
375
376 gtk_container_border_width(GTK_CONTAINER(hbox), BOX_BORDER);
377 if ((ctx->type != RCC_UI_MENU_OPTION)||(rccUiMenuGetRangeType(ctx) != RCC_OPTION_RANGE_TYPE_BOOLEAN)) {
378 label = gtk_label_new(title);
379 gtk_widget_show(label);
380 gtk_widget_set_usize(label, TITLE_WIDTH, TITLE_HEIGHT);
381 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 0);
382 }
383 gtk_widget_show((GtkWidget*)ctx->widget);
384 gtk_box_pack_start(GTK_BOX(hbox), (GtkWidget*)ctx->widget, TRUE, TRUE, 0);
385 return (rcc_ui_box)hbox;
386 }
387
rccUiFrameCreate(rcc_ui_frame_context ctx,const char * title)388 rcc_ui_frame rccUiFrameCreate(rcc_ui_frame_context ctx, const char *title) {
389 GtkWidget *frame, *box;
390
391 if (!ctx) return NULL;
392
393 frame = gtk_frame_new(title?title:"");
394 gtk_container_border_width(GTK_CONTAINER(frame), FRAME_BORDER);
395
396 #if GTK_MAJOR_VERSION > 2
397 box = gtk_box_new(GTK_ORIENTATION_VERTICAL, FRAME_SPACING);
398 #else /* GTK_MAJOR_VERSION < 3 */
399 box = gtk_vbox_new(FALSE, FRAME_SPACING);
400 #endif /* GTK_MAJOR_VERSION */
401 gtk_widget_show(box);
402 gtk_container_add(GTK_CONTAINER(frame), box);
403
404 return (rcc_ui_frame)frame;
405 }
406
rccUiFrameFree(rcc_ui_frame_context ctx)407 void rccUiFrameFree(rcc_ui_frame_context ctx) {
408 }
409
410
rccUiFrameAdd(rcc_ui_frame_context ctx,rcc_ui_box box)411 int rccUiFrameAdd(rcc_ui_frame_context ctx, rcc_ui_box box) {
412 GtkWidget *vbox;
413
414 if ((!ctx)||(!box)) return -1;
415
416 vbox = gtk_container_children(GTK_CONTAINER(ctx->frame))->data;
417 gtk_widget_show(GTK_WIDGET(box));
418 gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(box), FALSE, FALSE, 0);
419 return 0;
420 }
421
rccUiPageCreate(rcc_ui_context ctx,const char * title)422 rcc_ui_page rccUiPageCreate(rcc_ui_context ctx, const char *title) {
423 GtkWidget *vbox;
424 #if GTK_MAJOR_VERSION > 2
425 vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, PAGE_SPACING);
426 #else /* GTK_MAJOR_VERSION < 3 */
427 vbox = gtk_vbox_new(FALSE, PAGE_SPACING);
428 #endif /* GTK_MAJOR_VERSION */
429 return (rcc_ui_page)vbox;
430 }
431
rccUiPageAdd(rcc_ui_page page,rcc_ui_frame frame)432 int rccUiPageAdd(rcc_ui_page page, rcc_ui_frame frame) {
433 if ((!page)||(!frame)) return -1;
434 gtk_widget_show(frame);
435 gtk_box_pack_start(GTK_BOX(page), GTK_WIDGET(frame), FALSE, FALSE, 0);
436 return 0;
437 }
438