pcb 4.1.1
An interactive printed circuit board layout editor.
|
00001 /* 00002 * COPYRIGHT 00003 * 00004 * PCB, interactive printed circuit board design 00005 * Copyright (C) 1994,1995,1996 Thomas Nau 00006 * 00007 * This program is free software; you can redistribute it and/or modify 00008 * it under the terms of the GNU General Public License as published by 00009 * the Free Software Foundation; either version 2 of the License, or 00010 * (at your option) any later version. 00011 * 00012 * This program is distributed in the hope that it will be useful, 00013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00015 * GNU General Public License for more details. 00016 * 00017 * You should have received a copy of the GNU General Public License along 00018 * with this program; if not, write to the Free Software Foundation, Inc., 00019 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 00020 * 00021 */ 00022 00023 /* This module, gui-utils.c, was written by Bill Wilson and the functions 00024 * here are Copyright (C) 2004 by Bill Wilson. These functions are utility 00025 * functions which are taken from my other GPL'd projects gkrellm and 00026 * gstocks and are copied here for the Gtk PCB port. 00027 */ 00028 00029 #ifdef HAVE_CONFIG_H 00030 #include "config.h" 00031 #endif 00032 00033 #include "gui.h" 00034 #include <gdk/gdkkeysyms.h> 00035 00036 #ifdef HAVE_LIBDMALLOC 00037 #include <dmalloc.h> 00038 #endif 00039 00040 /* Not a gui function, but no better place to put it... 00041 */ 00042 gboolean 00043 dup_string (gchar ** dst, const gchar * src) 00044 { 00045 if ((dst == NULL) || ((*dst == NULL) && (src == NULL))) 00046 return FALSE; 00047 if (*dst) 00048 { 00049 if (src && !strcmp (*dst, src)) 00050 return FALSE; 00051 g_free (*dst); 00052 } 00053 *dst = g_strdup (src); 00054 return TRUE; 00055 } 00056 00057 void 00058 free_glist_and_data (GList ** list_head) 00059 { 00060 GList *list; 00061 00062 if (*list_head == NULL) 00063 return; 00064 for (list = *list_head; list; list = list->next) 00065 if (list->data) 00066 g_free (list->data); 00067 g_list_free (*list_head); 00068 *list_head = NULL; 00069 } 00070 00071 00072 gboolean 00073 ghid_is_modifier_key_sym (gint ksym) 00074 { 00075 if (ksym == GDK_Shift_R || ksym == GDK_Shift_L 00076 || ksym == GDK_Control_R || ksym == GDK_Control_L) 00077 return TRUE; 00078 return FALSE; 00079 } 00080 00081 00082 ModifierKeysState 00083 ghid_modifier_keys_state (GdkModifierType * state) 00084 { 00085 GdkModifierType mask; 00086 ModifierKeysState mk; 00087 gboolean shift, control, mod1; 00088 GHidPort *out = &ghid_port; 00089 00090 if (!state) 00091 gdk_window_get_pointer (gtk_widget_get_window (out->drawing_area), 00092 NULL, NULL, &mask); 00093 else 00094 mask = *state; 00095 00096 shift = (mask & GDK_SHIFT_MASK); 00097 control = (mask & GDK_CONTROL_MASK); 00098 mod1 = (mask & GDK_MOD1_MASK); 00099 00100 if (shift && !control && !mod1) 00101 mk = SHIFT_PRESSED; 00102 else if (!shift && control && !mod1) 00103 mk = CONTROL_PRESSED; 00104 else if (!shift && !control && mod1) 00105 mk = MOD1_PRESSED; 00106 else if (shift && control && !mod1) 00107 mk = SHIFT_CONTROL_PRESSED; 00108 else if (shift && !control && mod1) 00109 mk = SHIFT_MOD1_PRESSED; 00110 else if (!shift && control && mod1) 00111 mk = CONTROL_MOD1_PRESSED; 00112 else if (shift && control && mod1) 00113 mk = SHIFT_CONTROL_MOD1_PRESSED; 00114 else 00115 mk = NONE_PRESSED; 00116 00117 return mk; 00118 } 00119 00120 ButtonState 00121 ghid_button_state (GdkModifierType * state) 00122 { 00123 GdkModifierType mask; 00124 ButtonState bs; 00125 gboolean button1, button2, button3; 00126 GHidPort *out = &ghid_port; 00127 00128 if (!state) 00129 gdk_window_get_pointer (gtk_widget_get_window (out->drawing_area), 00130 NULL, NULL, &mask); 00131 else 00132 mask = *state; 00133 00134 button1 = (mask & GDK_BUTTON1_MASK); 00135 button2 = (mask & GDK_BUTTON2_MASK); 00136 button3 = (mask & GDK_BUTTON3_MASK); 00137 00138 if (button1) 00139 bs = BUTTON1_PRESSED; 00140 else if (button2) 00141 bs = BUTTON2_PRESSED; 00142 else if (button3) 00143 bs = BUTTON3_PRESSED; 00144 else 00145 bs = NO_BUTTON_PRESSED; 00146 00147 return bs; 00148 } 00149 00150 void 00151 ghid_draw_area_update (GHidPort * port, GdkRectangle * rect) 00152 { 00153 gdk_window_invalidate_rect (gtk_widget_get_window (port->drawing_area), 00154 rect, FALSE); 00155 } 00156 00157 00158 gchar * 00159 ghid_get_color_name (GdkColor * color) 00160 { 00161 gchar *name; 00162 00163 if (!color) 00164 name = g_strdup ("#000000"); 00165 else 00166 name = g_strdup_printf ("#%2.2x%2.2x%2.2x", 00167 (color->red >> 8) & 0xff, 00168 (color->green >> 8) & 0xff, 00169 (color->blue >> 8) & 0xff); 00170 return name; 00171 } 00172 00173 void 00174 ghid_map_color_string (char *color_string, GdkColor * color) 00175 { 00176 static GdkColormap *colormap = NULL; 00177 GHidPort *out = &ghid_port; 00178 00179 if (!color || !out->top_window) 00180 return; 00181 if (colormap == NULL) 00182 colormap = gtk_widget_get_colormap (out->top_window); 00183 if (color->red || color->green || color->blue) 00184 gdk_colormap_free_colors (colormap, color, 1); 00185 gdk_color_parse (color_string, color); 00186 gdk_color_alloc (colormap, color); 00187 } 00188 00189 00190 gchar * 00191 ghid_entry_get_text (GtkWidget * entry) 00192 { 00193 gchar *s = ""; 00194 00195 if (entry) 00196 s = (gchar *) gtk_entry_get_text (GTK_ENTRY (entry)); 00197 while (*s == ' ' || *s == '\t') 00198 ++s; 00199 return s; 00200 } 00201 00202 00203 00204 void 00205 ghid_check_button_connected (GtkWidget * box, 00206 GtkWidget ** button, 00207 gboolean active, 00208 gboolean pack_start, 00209 gboolean expand, 00210 gboolean fill, 00211 gint pad, 00212 void (*cb_func) (GtkToggleButton *, gpointer), 00213 gpointer data, gchar * string) 00214 { 00215 GtkWidget *b; 00216 00217 if (!string) 00218 return; 00219 b = gtk_check_button_new_with_mnemonic (string); 00220 gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (b), active); 00221 if (box && pack_start) 00222 gtk_box_pack_start (GTK_BOX (box), b, expand, fill, pad); 00223 else if (box && !pack_start) 00224 gtk_box_pack_end (GTK_BOX (box), b, expand, fill, pad); 00225 00226 if (cb_func) 00227 g_signal_connect (b, "clicked", G_CALLBACK (cb_func), data); 00228 if (button) 00229 *button = b; 00230 } 00231 00232 void 00233 ghid_button_connected (GtkWidget * box, GtkWidget ** button, 00234 gboolean pack_start, gboolean expand, gboolean fill, 00235 gint pad, void (*cb_func) (gpointer), gpointer data, 00236 gchar * string) 00237 { 00238 GtkWidget *b; 00239 00240 if (!string) 00241 return; 00242 b = gtk_button_new_with_mnemonic (string); 00243 if (box && pack_start) 00244 gtk_box_pack_start (GTK_BOX (box), b, expand, fill, pad); 00245 else if (box && !pack_start) 00246 gtk_box_pack_end (GTK_BOX (box), b, expand, fill, pad); 00247 00248 if (cb_func) 00249 g_signal_connect (b, "clicked", G_CALLBACK (cb_func), data); 00250 if (button) 00251 *button = b; 00252 } 00253 00254 void 00255 ghid_coord_entry (GtkWidget * box, GtkWidget ** coord_entry, Coord value, 00256 Coord low, Coord high, enum ce_step_size step_size, 00257 gint width, void (*cb_func) (GHidCoordEntry *, gpointer), 00258 gpointer data, gboolean right_align, gchar * string) 00259 { 00260 GtkWidget *hbox = NULL, *label, *entry_widget; 00261 GHidCoordEntry *entry; 00262 00263 if (string && box) 00264 { 00265 hbox = gtk_hbox_new (FALSE, 0); 00266 gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 2); 00267 box = hbox; 00268 } 00269 00270 entry_widget = ghid_coord_entry_new (low, high, value, Settings.grid_unit, step_size); 00271 if (coord_entry) 00272 *coord_entry = entry_widget; 00273 if (width > 0) 00274 gtk_widget_set_size_request (entry_widget, width, -1); 00275 entry = GHID_COORD_ENTRY (entry_widget); 00276 if (data == NULL) 00277 data = (gpointer) entry; 00278 if (cb_func) 00279 g_signal_connect (G_OBJECT (entry_widget), "value_changed", 00280 G_CALLBACK (cb_func), data); 00281 if (box) 00282 { 00283 if (right_align && string) 00284 { 00285 label = gtk_label_new (string); 00286 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); 00287 gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 2); 00288 } 00289 gtk_box_pack_start (GTK_BOX (box), entry_widget, FALSE, FALSE, 2); 00290 if (!right_align && string) 00291 { 00292 label = gtk_label_new (string); 00293 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); 00294 gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 2); 00295 } 00296 } 00297 } 00298 00299 void 00300 ghid_spin_button (GtkWidget * box, GtkWidget ** spin_button, gfloat value, 00301 gfloat low, gfloat high, gfloat step0, gfloat step1, 00302 gint digits, gint width, 00303 void (*cb_func) (GtkSpinButton *, gpointer), gpointer data, gboolean right_align, 00304 gchar * string) 00305 { 00306 GtkWidget *hbox = NULL, *label, *spin_but; 00307 GtkSpinButton *spin; 00308 GtkAdjustment *adj; 00309 00310 if (string && box) 00311 { 00312 hbox = gtk_hbox_new (FALSE, 0); 00313 gtk_box_pack_start (GTK_BOX (box), hbox, FALSE, FALSE, 2); 00314 box = hbox; 00315 } 00316 adj = (GtkAdjustment *) gtk_adjustment_new (value, 00317 low, high, step0, step1, 0.0); 00318 spin_but = gtk_spin_button_new (adj, 0.5, digits); 00319 if (spin_button) 00320 *spin_button = spin_but; 00321 if (width > 0) 00322 gtk_widget_set_size_request (spin_but, width, -1); 00323 spin = GTK_SPIN_BUTTON (spin_but); 00324 gtk_spin_button_set_numeric (spin, TRUE); 00325 if (data == NULL) 00326 data = (gpointer) spin; 00327 if (cb_func) 00328 g_signal_connect (G_OBJECT (spin_but), "value_changed", 00329 G_CALLBACK (cb_func), data); 00330 if (box) 00331 { 00332 if (right_align && string) 00333 { 00334 label = gtk_label_new (string); 00335 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); 00336 gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 2); 00337 } 00338 gtk_box_pack_start (GTK_BOX (box), spin_but, FALSE, FALSE, 2); 00339 if (!right_align && string) 00340 { 00341 label = gtk_label_new (string); 00342 gtk_misc_set_alignment (GTK_MISC (label), 0, 0.5); 00343 gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 2); 00344 } 00345 } 00346 } 00347 00348 void 00349 ghid_table_coord_entry (GtkWidget * table, gint row, gint column, 00350 GtkWidget ** coord_entry, Coord value, 00351 Coord low, Coord high, enum ce_step_size step_size, 00352 gint width, void (*cb_func) (GHidCoordEntry *, gpointer), 00353 gpointer data, gboolean right_align, gchar * string) 00354 { 00355 GtkWidget *label, *entry_widget; 00356 GHidCoordEntry *entry; 00357 00358 if (!table) 00359 return; 00360 00361 entry_widget = ghid_coord_entry_new (low, high, value, Settings.grid_unit, step_size); 00362 if (coord_entry) 00363 *coord_entry = entry_widget; 00364 if (width > 0) 00365 gtk_widget_set_size_request (entry_widget, width, -1); 00366 entry = GHID_COORD_ENTRY (entry_widget); 00367 if (data == NULL) 00368 data = (gpointer) entry; 00369 if (cb_func) 00370 g_signal_connect (G_OBJECT (entry), "value_changed", 00371 G_CALLBACK (cb_func), data); 00372 00373 if (right_align) 00374 { 00375 gtk_table_attach_defaults (GTK_TABLE (table), entry_widget, 00376 column + 1, column + 2, row, row + 1); 00377 if (string) 00378 { 00379 label = gtk_label_new (string); 00380 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); 00381 gtk_table_attach_defaults (GTK_TABLE (table), label, 00382 column, column + 1, row, row + 1); 00383 } 00384 } 00385 else 00386 { 00387 gtk_table_attach_defaults (GTK_TABLE (table), entry_widget, 00388 column, column + 1, row, row + 1); 00389 if (string) 00390 { 00391 label = gtk_label_new (string); 00392 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); 00393 gtk_table_attach_defaults (GTK_TABLE (table), label, 00394 column + 1, column + 2, row, row + 1); 00395 } 00396 } 00397 } 00398 00399 00400 void 00401 ghid_table_spin_button (GtkWidget * table, gint row, gint column, 00402 GtkWidget ** spin_button, gfloat value, 00403 gfloat low, gfloat high, gfloat step0, gfloat step1, 00404 gint digits, gint width, 00405 void (*cb_func) (GtkSpinButton *, gpointer), gpointer data, 00406 gboolean right_align, gchar * string) 00407 { 00408 GtkWidget *label, *spin_but; 00409 GtkSpinButton *spin; 00410 GtkAdjustment *adj; 00411 00412 if (!table) 00413 return; 00414 00415 adj = (GtkAdjustment *) gtk_adjustment_new (value, 00416 low, high, step0, step1, 0.0); 00417 spin_but = gtk_spin_button_new (adj, 0.5, digits); 00418 00419 if (spin_button) 00420 *spin_button = spin_but; 00421 if (width > 0) 00422 gtk_widget_set_size_request (spin_but, width, -1); 00423 spin = GTK_SPIN_BUTTON (spin_but); 00424 gtk_spin_button_set_numeric (spin, TRUE); 00425 if (data == NULL) 00426 data = (gpointer) spin; 00427 if (cb_func) 00428 g_signal_connect (G_OBJECT (spin_but), "value_changed", 00429 G_CALLBACK (cb_func), data); 00430 00431 if (right_align) 00432 { 00433 gtk_table_attach_defaults (GTK_TABLE (table), spin_but, 00434 column + 1, column + 2, row, row + 1); 00435 if (string) 00436 { 00437 label = gtk_label_new (string); 00438 gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5); 00439 gtk_table_attach_defaults (GTK_TABLE (table), label, 00440 column, column + 1, row, row + 1); 00441 } 00442 } 00443 else 00444 { 00445 gtk_table_attach_defaults (GTK_TABLE (table), spin_but, 00446 column, column + 1, row, row + 1); 00447 if (string) 00448 { 00449 label = gtk_label_new (string); 00450 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); 00451 gtk_table_attach_defaults (GTK_TABLE (table), label, 00452 column + 1, column + 2, row, row + 1); 00453 } 00454 } 00455 } 00456 00457 void 00458 ghid_range_control (GtkWidget * box, GtkWidget ** scale_res, 00459 gboolean horizontal, GtkPositionType pos, 00460 gboolean set_draw_value, gint digits, gboolean pack_start, 00461 gboolean expand, gboolean fill, guint pad, gfloat value, 00462 gfloat low, gfloat high, gfloat step0, gfloat step1, 00463 void (*cb_func) (), gpointer data) 00464 { 00465 GtkWidget *scale; 00466 GtkAdjustment *adj; 00467 00468 adj = (GtkAdjustment *) gtk_adjustment_new (value, 00469 low, high, step0, step1, 0.0); 00470 00471 if (horizontal) 00472 scale = gtk_hscale_new (GTK_ADJUSTMENT (adj)); 00473 else 00474 scale = gtk_vscale_new (GTK_ADJUSTMENT (adj)); 00475 gtk_scale_set_value_pos (GTK_SCALE (scale), pos); 00476 gtk_scale_set_draw_value (GTK_SCALE (scale), set_draw_value); 00477 gtk_scale_set_digits (GTK_SCALE (scale), digits); 00478 00479 /* Increments don't make sense, use -1,1 because that does closest to 00480 | what I want: scroll down decrements slider value. 00481 */ 00482 gtk_range_set_increments (GTK_RANGE (scale), -1, 1); 00483 00484 if (pack_start) 00485 gtk_box_pack_start (GTK_BOX (box), scale, expand, fill, pad); 00486 else 00487 gtk_box_pack_end (GTK_BOX (box), scale, expand, fill, pad); 00488 00489 if (data == NULL) 00490 data = (gpointer) adj; 00491 if (cb_func) 00492 g_signal_connect (G_OBJECT (adj), "value_changed", 00493 G_CALLBACK (cb_func), data); 00494 if (scale_res) 00495 *scale_res = scale; 00496 } 00497 00498 GtkWidget * 00499 ghid_scrolled_vbox (GtkWidget * box, GtkWidget ** scr, 00500 GtkPolicyType h_policy, GtkPolicyType v_policy) 00501 { 00502 GtkWidget *scrolled, *vbox; 00503 00504 scrolled = gtk_scrolled_window_new (NULL, NULL); 00505 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), 00506 h_policy, v_policy); 00507 gtk_box_pack_start (GTK_BOX (box), scrolled, TRUE, TRUE, 0); 00508 vbox = gtk_vbox_new (FALSE, 0); 00509 gtk_scrolled_window_add_with_viewport (GTK_SCROLLED_WINDOW (scrolled), 00510 vbox); 00511 if (scr) 00512 *scr = scrolled; 00513 return vbox; 00514 } 00515 00516 /* frame_border_width - border around outside of frame. 00517 | vbox_pad - pad between widgets to be packed in returned vbox. 00518 | vbox_border_width - border between returned vbox and frame. 00519 */ 00520 GtkWidget * 00521 ghid_framed_vbox (GtkWidget * box, gchar * label, gint frame_border_width, 00522 gboolean frame_expand, gint vbox_pad, 00523 gint vbox_border_width) 00524 { 00525 GtkWidget *frame; 00526 GtkWidget *vbox; 00527 00528 frame = gtk_frame_new (label); 00529 gtk_container_set_border_width (GTK_CONTAINER (frame), frame_border_width); 00530 gtk_box_pack_start (GTK_BOX (box), frame, frame_expand, frame_expand, 0); 00531 vbox = gtk_vbox_new (FALSE, vbox_pad); 00532 gtk_container_set_border_width (GTK_CONTAINER (vbox), vbox_border_width); 00533 gtk_container_add (GTK_CONTAINER (frame), vbox); 00534 return vbox; 00535 } 00536 00537 GtkWidget * 00538 ghid_framed_vbox_end (GtkWidget * box, gchar * label, gint frame_border_width, 00539 gboolean frame_expand, gint vbox_pad, 00540 gint vbox_border_width) 00541 { 00542 GtkWidget *frame; 00543 GtkWidget *vbox; 00544 00545 frame = gtk_frame_new (label); 00546 gtk_container_set_border_width (GTK_CONTAINER (frame), frame_border_width); 00547 gtk_box_pack_end (GTK_BOX (box), frame, frame_expand, frame_expand, 0); 00548 vbox = gtk_vbox_new (FALSE, vbox_pad); 00549 gtk_container_set_border_width (GTK_CONTAINER (vbox), vbox_border_width); 00550 gtk_container_add (GTK_CONTAINER (frame), vbox); 00551 return vbox; 00552 } 00553 00554 GtkWidget * 00555 ghid_category_vbox (GtkWidget * box, const gchar * category_header, 00556 gint header_pad, 00557 gint box_pad, gboolean pack_start, gboolean bottom_pad) 00558 { 00559 GtkWidget *vbox, *vbox1, *hbox, *label; 00560 gchar *s; 00561 00562 vbox = gtk_vbox_new (FALSE, 0); 00563 if (pack_start) 00564 gtk_box_pack_start (GTK_BOX (box), vbox, FALSE, FALSE, 0); 00565 else 00566 gtk_box_pack_end (GTK_BOX (box), vbox, FALSE, FALSE, 0); 00567 00568 if (category_header) 00569 { 00570 label = gtk_label_new (NULL); 00571 s = g_strconcat ("<span weight=\"bold\">", category_header, 00572 "</span>", NULL); 00573 gtk_label_set_markup (GTK_LABEL (label), s); 00574 gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5); 00575 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, header_pad); 00576 g_free (s); 00577 } 00578 00579 hbox = gtk_hbox_new (FALSE, 0); 00580 gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0); 00581 label = gtk_label_new (" "); 00582 gtk_box_pack_start (GTK_BOX (hbox), label, FALSE, FALSE, 0); 00583 vbox1 = gtk_vbox_new (FALSE, box_pad); 00584 gtk_box_pack_start (GTK_BOX (hbox), vbox1, TRUE, TRUE, 0); 00585 00586 if (bottom_pad) 00587 { 00588 label = gtk_label_new (""); 00589 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); 00590 } 00591 return vbox1; 00592 } 00593 00594 GtkTreeSelection * 00595 ghid_scrolled_selection (GtkTreeView * treeview, GtkWidget * box, 00596 GtkSelectionMode s_mode, 00597 GtkPolicyType h_policy, GtkPolicyType v_policy, 00598 void (*func_cb) (GtkTreeSelection *, gpointer), gpointer data) 00599 { 00600 GtkTreeSelection *selection; 00601 GtkWidget *scrolled; 00602 00603 if (!box || !treeview) 00604 return NULL; 00605 00606 scrolled = gtk_scrolled_window_new (NULL, NULL); 00607 gtk_box_pack_start (GTK_BOX (box), scrolled, TRUE, TRUE, 0); 00608 gtk_container_add (GTK_CONTAINER (scrolled), GTK_WIDGET (treeview)); 00609 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), 00610 h_policy, v_policy); 00611 selection = gtk_tree_view_get_selection (treeview); 00612 gtk_tree_selection_set_mode (selection, s_mode); 00613 if (func_cb) 00614 g_signal_connect (G_OBJECT (selection), "changed", 00615 G_CALLBACK (func_cb), data); 00616 return selection; 00617 } 00618 00619 GtkWidget * 00620 ghid_notebook_page (GtkWidget * tabs, const char *name, gint pad, gint border) 00621 { 00622 GtkWidget *label; 00623 GtkWidget *vbox; 00624 00625 vbox = gtk_vbox_new (FALSE, pad); 00626 gtk_container_set_border_width (GTK_CONTAINER (vbox), border); 00627 00628 label = gtk_label_new (name); 00629 gtk_notebook_append_page (GTK_NOTEBOOK (tabs), vbox, label); 00630 00631 return vbox; 00632 } 00633 00634 GtkWidget * 00635 ghid_framed_notebook_page (GtkWidget * tabs, char *name, gint border, 00636 gint frame_border, gint vbox_pad, gint vbox_border) 00637 { 00638 GtkWidget *vbox; 00639 00640 vbox = ghid_notebook_page (tabs, name, 0, border); 00641 vbox = ghid_framed_vbox (vbox, NULL, frame_border, TRUE, 00642 vbox_pad, vbox_border); 00643 return vbox; 00644 } 00645 00646 void 00647 ghid_dialog_report (gchar * title, gchar * message) 00648 { 00649 GtkWidget *top_win; 00650 GtkWidget *dialog; 00651 GtkWidget *content_area; 00652 GtkWidget *scrolled; 00653 GtkWidget *vbox, *vbox1; 00654 GtkWidget *label; 00655 gchar *s; 00656 gint nlines; 00657 GHidPort *out = &ghid_port; 00658 00659 if (!message) 00660 return; 00661 top_win = out->top_window; 00662 dialog = gtk_dialog_new_with_buttons (title ? title : "PCB", 00663 GTK_WINDOW (top_win), 00664 GTK_DIALOG_DESTROY_WITH_PARENT, 00665 GTK_STOCK_OK, GTK_RESPONSE_NONE, 00666 NULL); 00667 g_signal_connect_swapped (GTK_OBJECT (dialog), "response", 00668 G_CALLBACK (gtk_widget_destroy), 00669 GTK_OBJECT (dialog)); 00670 gtk_window_set_wmclass (GTK_WINDOW (dialog), "PCB_Dialog", "PCB"); 00671 00672 content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); 00673 00674 vbox = gtk_vbox_new (FALSE, 0); 00675 gtk_container_set_border_width (GTK_CONTAINER (vbox), 8); 00676 gtk_box_pack_start (GTK_BOX (content_area), vbox, FALSE, FALSE, 0); 00677 00678 label = gtk_label_new (message); 00679 gtk_label_set_justify (GTK_LABEL (label), GTK_JUSTIFY_LEFT); 00680 00681 for (nlines = 0, s = message; *s; ++s) 00682 if (*s == '\n') 00683 ++nlines; 00684 if (nlines > 20) 00685 { 00686 vbox1 = ghid_scrolled_vbox (vbox, &scrolled, 00687 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC); 00688 gtk_widget_set_size_request (scrolled, -1, 300); 00689 gtk_box_pack_start (GTK_BOX (vbox1), label, FALSE, FALSE, 0); 00690 } 00691 else 00692 gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0); 00693 00694 gtk_widget_show_all (dialog); 00695 } 00696 00697 00698 void 00699 ghid_label_set_markup (GtkWidget * label, const gchar * text) 00700 { 00701 if (label) 00702 gtk_label_set_markup (GTK_LABEL (label), text ? text : ""); 00703 } 00704 00705 00706 static void 00707 text_view_append (GtkWidget * view, gchar * s) 00708 { 00709 GtkTextIter iter; 00710 GtkTextBuffer *buffer; 00711 GtkTextMark *mark; 00712 00713 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); 00714 gtk_text_buffer_get_end_iter (buffer, &iter); 00715 /* gtk_text_iter_forward_to_end(&iter); */ 00716 00717 if (strncmp (s, "<b>", 3) == 0) 00718 gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, 00719 s + 3, -1, "bold", NULL); 00720 else if (strncmp (s, "<i>", 3) == 0) 00721 gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, 00722 s + 3, -1, "italic", NULL); 00723 else if (strncmp (s, "<h>", 3) == 0) 00724 gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, 00725 s + 3, -1, "heading", NULL); 00726 else if (strncmp (s, "<c>", 3) == 0) 00727 gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, 00728 s + 3, -1, "center", NULL); 00729 else if (strncmp (s, "<ul>", 4) == 0) 00730 gtk_text_buffer_insert_with_tags_by_name (buffer, &iter, 00731 s + 4, -1, "underline", NULL); 00732 else 00733 gtk_text_buffer_insert (buffer, &iter, s, -1); 00734 00735 mark = gtk_text_buffer_create_mark (buffer, NULL, &iter, FALSE); 00736 gtk_text_view_scroll_to_mark (GTK_TEXT_VIEW (view), mark, 00737 0, TRUE, 0.0, 1.0); 00738 gtk_text_buffer_delete_mark (buffer, mark); 00739 } 00740 00741 void 00742 ghid_text_view_append (GtkWidget * view, gchar * string) 00743 { 00744 static gchar *tag; 00745 gchar *s; 00746 00747 s = string; 00748 if (*s == '<' 00749 && ((*(s + 2) == '>' && !*(s + 3)) || (*(s + 3) == '>' && !*(s + 4)))) 00750 { 00751 tag = g_strdup (s); 00752 return; 00753 } 00754 00755 if (tag) 00756 { 00757 s = g_strconcat (tag, string, NULL); 00758 text_view_append (view, s); 00759 g_free (s); 00760 g_free (tag); 00761 tag = NULL; 00762 } 00763 else 00764 text_view_append (view, string); 00765 } 00766 00767 void 00768 ghid_text_view_append_strings (GtkWidget * view, gchar ** string, 00769 gint n_strings) 00770 { 00771 gchar *tag = NULL; 00772 gchar *s, *t; 00773 gint i; 00774 00775 for (i = 0; i < n_strings; ++i) 00776 { 00777 s = string[i]; 00778 if (*s == '<' 00779 && ((*(s + 2) == '>' && !*(s + 3)) 00780 || (*(s + 3) == '>' && !*(s + 4)))) 00781 { 00782 tag = g_strdup (s); 00783 continue; 00784 } 00785 s = _(string[i]); 00786 if (tag) 00787 { 00788 t = g_strconcat (tag, s, NULL); 00789 text_view_append (view, t); 00790 g_free (t); 00791 g_free (tag); 00792 tag = NULL; 00793 } 00794 else 00795 text_view_append (view, s); 00796 } 00797 } 00798 00799 00800 GtkWidget * 00801 ghid_scrolled_text_view (GtkWidget * box, 00802 GtkWidget ** scr, 00803 GtkPolicyType h_policy, GtkPolicyType v_policy) 00804 { 00805 GtkWidget *scrolled, *view; 00806 GtkTextBuffer *buffer; 00807 00808 scrolled = gtk_scrolled_window_new (NULL, NULL); 00809 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled), 00810 h_policy, v_policy); 00811 gtk_box_pack_start (GTK_BOX (box), scrolled, TRUE, TRUE, 0); 00812 00813 view = gtk_text_view_new (); 00814 gtk_text_view_set_editable (GTK_TEXT_VIEW (view), FALSE); 00815 buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view)); 00816 gtk_text_buffer_create_tag (buffer, "heading", 00817 "weight", PANGO_WEIGHT_BOLD, 00818 "size", 14 * PANGO_SCALE, NULL); 00819 gtk_text_buffer_create_tag (buffer, "italic", 00820 "style", PANGO_STYLE_ITALIC, NULL); 00821 gtk_text_buffer_create_tag (buffer, "bold", 00822 "weight", PANGO_WEIGHT_BOLD, NULL); 00823 gtk_text_buffer_create_tag (buffer, "center", 00824 "justification", GTK_JUSTIFY_CENTER, NULL); 00825 gtk_text_buffer_create_tag (buffer, "underline", 00826 "underline", PANGO_UNDERLINE_SINGLE, NULL); 00827 00828 gtk_container_add (GTK_CONTAINER (scrolled), view); 00829 if (scr) 00830 *scr = scrolled; 00831 return view; 00832 }