gschem
|
00001 /* gEDA - GPL Electronic Design Automation 00002 * gschem - gEDA Schematic Capture 00003 * Copyright (C) 1998-2010 Ales Hvezda 00004 * Copyright (C) 1998-2010 gEDA Contributors (see ChangeLog for details) 00005 * 00006 * This program is free software; you can redistribute it and/or modify 00007 * it under the terms of the GNU General Public License as published by 00008 * the Free Software Foundation; either version 2 of the License, or 00009 * (at your option) any later version. 00010 * 00011 * This program is distributed in the hope that it will be useful, 00012 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00014 * GNU General Public License for more details. 00015 * 00016 * You should have received a copy of the GNU General Public License 00017 * along with this program; if not, write to the Free Software 00018 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 00019 */ 00021 #include <config.h> 00022 #include <version.h> 00023 #include <missing.h> 00024 00025 #include <stdio.h> 00026 #ifdef HAVE_STDLIB_H 00027 #include <stdlib.h> 00028 #endif 00029 #ifdef HAVE_STRING_H 00030 #include <string.h> 00031 #endif 00032 00033 #include "gschem.h" 00034 00035 #ifdef HAVE_LIBDMALLOC 00036 #include <dmalloc.h> 00037 #endif 00038 00039 #define GLADE_HOOKUP_OBJECT(component,widget,name) \ 00040 g_object_set_data_full (G_OBJECT (component), name, \ 00041 gtk_widget_ref (widget), (GDestroyNotify) gtk_widget_unref) 00042 00043 static GtkWidget* create_menu_linetype (GSCHEM_TOPLEVEL *w_current); 00044 static gint line_type_dialog_linetype_change (GtkWidget *w, gpointer data); 00045 static void line_type_dialog_ok (GtkWidget *w, gpointer data); 00046 00047 static GtkWidget* create_menu_filltype (GSCHEM_TOPLEVEL *w_current); 00048 static gint fill_type_dialog_filltype_change(GtkWidget *w, gpointer data); 00049 static void fill_type_dialog_ok(GtkWidget *w, gpointer data); 00050 00051 00052 struct line_type_data { 00053 GtkWidget *dialog; 00054 GtkWidget *width_entry; 00055 GtkWidget *line_type; 00056 GtkWidget *length_entry; 00057 GtkWidget *space_entry; 00058 00059 GSCHEM_TOPLEVEL *w_current; 00060 }; 00061 00062 struct fill_type_data { 00063 GtkWidget *dialog; 00064 GtkWidget *fill_type; 00065 GtkWidget *width_entry; 00066 GtkWidget *angle1_entry; 00067 GtkWidget *pitch1_entry; 00068 GtkWidget *angle2_entry; 00069 GtkWidget *pitch2_entry; 00070 00071 GSCHEM_TOPLEVEL *w_current; 00072 }; 00073 00079 void destroy_window(GtkWidget *widget, GtkWidget **window) 00080 { 00081 *window = NULL; 00082 } 00083 00084 /* TODO: This string is used by the dialogs: show_text, find_text and hide_text 00085 * I think it should be removed. (Werner Hoch) 00086 */ 00087 char generic_textstring[256] = "refdes=R"; 00088 00089 /***************** Start of Text Input dialog box *********************/ 00090 00095 void text_input_dialog_apply(GtkWidget *w, GSCHEM_TOPLEVEL *w_current) 00096 { 00097 gchar *string = NULL; 00098 gchar *tmp = NULL; 00099 GtkWidget *tientry; 00100 GtkTextBuffer *textbuffer; 00101 GtkTextIter start, end; 00102 00103 tientry = gtk_object_get_data(GTK_OBJECT(w_current->tiwindow),"tientry"); 00104 00105 textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(tientry)); 00106 gtk_text_buffer_get_bounds (textbuffer, &start, &end); 00107 string = gtk_text_iter_get_text (&start, &end); 00108 00109 if (string[0] == '\0' ) 00110 return; 00111 00112 switch(w_current->text_caps) { 00113 case(LOWER): 00114 tmp = g_utf8_strdown (string, -1); 00115 break; 00116 00117 case(UPPER): 00118 tmp = g_utf8_strup (string, -1); 00119 break; 00120 00121 case(BOTH): 00122 default: 00123 /* do nothing */ 00124 break; 00125 } 00126 00127 /* select the text, so you can continue immediatly writing the next text */ 00128 select_all_text_in_textview(GTK_TEXT_VIEW(tientry)); 00129 gtk_widget_grab_focus(tientry); 00130 00131 w_current->toplevel->page_current->CHANGED=1; 00132 00133 o_text_prepare_place (w_current, tmp == NULL ? string : tmp); 00134 g_free (string); 00135 g_free (tmp); 00136 } 00137 00142 void text_input_dialog_response(GtkWidget * widget, gint response, GSCHEM_TOPLEVEL *w_current) 00143 { 00144 switch(response) { 00145 case GTK_RESPONSE_ACCEPT: 00146 text_input_dialog_apply(widget, w_current); 00147 break; 00148 case GTK_RESPONSE_REJECT: 00149 case GTK_RESPONSE_DELETE_EVENT: 00150 i_set_state(w_current, SELECT); 00151 i_update_toolbar(w_current); 00152 gtk_widget_destroy(w_current->tiwindow); 00153 w_current->tiwindow=NULL; 00154 break; 00155 default: 00156 printf("text_edit_dialog_response(): strange signal %d\n", response); 00157 } 00158 } 00159 00160 00165 void text_input_dialog (GSCHEM_TOPLEVEL *w_current) 00166 { 00167 GtkWidget *label = NULL; 00168 GtkWidget *tientry = NULL; 00169 GtkWidget *vbox; 00170 GtkWidget *viewport1 = NULL; 00171 GtkWidget *scrolled_window = NULL; 00172 PangoTabArray *tab_array; 00173 int real_tab_width; 00174 00175 if (!w_current->tiwindow) { /* dialog not created yet */ 00176 w_current->tiwindow = gschem_dialog_new_with_buttons(_("Text Entry..."), 00177 GTK_WINDOW(w_current->main_window), 00178 0, /* NON_MODAL */ 00179 "text-entry", w_current, 00180 GTK_STOCK_CLOSE, 00181 GTK_RESPONSE_REJECT, 00182 GTK_STOCK_APPLY, 00183 GTK_RESPONSE_ACCEPT, 00184 NULL); 00185 00186 /* Set the alternative button order (ok, cancel, help) for other systems */ 00187 gtk_dialog_set_alternative_button_order(GTK_DIALOG(w_current->tiwindow), 00188 GTK_RESPONSE_ACCEPT, 00189 GTK_RESPONSE_REJECT, 00190 -1); 00191 00192 gtk_window_position(GTK_WINDOW (w_current->tiwindow), 00193 GTK_WIN_POS_NONE); 00194 00195 g_signal_connect (G_OBJECT (w_current->tiwindow), "response", 00196 G_CALLBACK (text_input_dialog_response), 00197 w_current); 00198 00199 gtk_dialog_set_default_response(GTK_DIALOG(w_current->tiwindow), 00200 GTK_RESPONSE_ACCEPT); 00201 00202 gtk_container_border_width(GTK_CONTAINER (w_current->tiwindow), 00203 DIALOG_BORDER_SPACING); 00204 vbox = GTK_DIALOG(w_current->tiwindow)->vbox; 00205 gtk_box_set_spacing(GTK_BOX(vbox),DIALOG_V_SPACING); 00206 00207 label = gtk_label_new (_("Enter text, click apply,\n" 00208 "move cursor into window, click to place text.\n" 00209 "Middle button to rotate while placing.")); 00210 gtk_misc_set_alignment(GTK_MISC(label),0,0); 00211 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); 00212 00213 viewport1 = gtk_viewport_new (NULL, NULL); 00214 gtk_widget_show (viewport1); 00215 00216 scrolled_window = gtk_scrolled_window_new(NULL, NULL); 00217 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), 00218 GTK_POLICY_AUTOMATIC, 00219 GTK_POLICY_AUTOMATIC); 00220 gtk_container_add (GTK_CONTAINER (viewport1), scrolled_window); 00221 gtk_box_pack_start( GTK_BOX(vbox), viewport1, TRUE, TRUE, 0); 00222 00223 tientry = gtk_text_view_new(); 00224 gtk_text_view_set_editable(GTK_TEXT_VIEW(tientry), TRUE); 00225 select_all_text_in_textview(GTK_TEXT_VIEW(tientry)); 00226 00227 /* Set the tab width, using pango tab array */ 00229 tab_array = pango_tab_array_new (1, TRUE); 00230 real_tab_width = text_view_calculate_real_tab_width(GTK_TEXT_VIEW(tientry), 00231 tab_in_chars); 00232 if (real_tab_width >= 0) { 00233 pango_tab_array_set_tab (tab_array, 0, PANGO_TAB_LEFT, real_tab_width); 00234 /* printf("Real tab width: %i\n", real_tab_width);*/ 00235 gtk_text_view_set_tabs (GTK_TEXT_VIEW (tientry), 00236 tab_array); 00237 } 00238 else { 00239 g_warning ("text_input_dialog: Impossible to set tab width.\n"); 00240 } 00241 pango_tab_array_free (tab_array); 00242 gtk_container_add(GTK_CONTAINER(scrolled_window), tientry); 00243 00244 gtk_object_set_data(GTK_OBJECT(w_current->tiwindow), 00245 "tientry",tientry); 00246 00247 gtk_widget_show_all (w_current->tiwindow); 00248 } 00249 else { /* dialog already created */ 00250 gtk_window_present (GTK_WINDOW(w_current->tiwindow)); 00251 } 00252 00253 /* always select the text in the entry */ 00254 tientry = gtk_object_get_data(GTK_OBJECT(w_current->tiwindow),"tientry"); 00255 select_all_text_in_textview(GTK_TEXT_VIEW(tientry)); 00256 gtk_widget_grab_focus(tientry); 00257 } 00258 00259 /***************** End of Text Input dialog box ***********************/ 00260 00261 /***************** Start of Text Edit dialog box **********************/ 00269 gint change_alignment(GtkComboBox *w, GSCHEM_TOPLEVEL *w_current) 00270 { 00271 GtkTreeIter iter; 00272 GtkTreeModel *model; 00273 gint value; 00274 if( gtk_combo_box_get_active_iter(w, &iter)) 00275 { 00276 model = gtk_combo_box_get_model(w); 00277 gtk_tree_model_get(model, &iter, 1, &value, -1); 00278 w_current->text_alignment = value; 00279 } 00280 00281 /*w_current->page_current->CHANGED=1; I don't think this belongs */ 00282 /* o_undo_savestate(w_current, UNDO_ALL); I don't think this belongs */ 00283 00284 return 0; 00285 } 00286 00293 static GtkListStore *create_menu_alignment (GSCHEM_TOPLEVEL *w_current) 00294 { 00295 GtkListStore *store; 00296 GtkTreeIter iter; 00297 00298 store = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_INT); 00299 00300 gtk_list_store_append(store, &iter); 00301 gtk_list_store_set(store, &iter, 0, _("Upper Left"), -1); 00302 gtk_list_store_set(store, &iter, 1, 2, -1); 00303 gtk_list_store_append(store, &iter); 00304 gtk_list_store_set(store, &iter, 0, _("Upper Middle"), -1); 00305 gtk_list_store_set(store, &iter, 1, 5, -1); 00306 gtk_list_store_append( store, &iter); 00307 gtk_list_store_set(store, &iter, 0, _("Upper Right"), -1); 00308 gtk_list_store_set(store, &iter, 1, 8, -1); 00309 00310 gtk_list_store_append(store, &iter); 00311 gtk_list_store_set(store, &iter, 0, _("Middle Left"), -1); 00312 gtk_list_store_set(store, &iter, 1, 1, -1); 00313 gtk_list_store_append(store, &iter); 00314 gtk_list_store_set(store, &iter, 0, _("Middle Middle"), -1); 00315 gtk_list_store_set(store, &iter, 1, 4, -1); 00316 gtk_list_store_append(store, &iter); 00317 gtk_list_store_set(store, &iter, 0, _("Middle Right"), -1); 00318 gtk_list_store_set(store, &iter, 1, 7, -1); 00319 00320 gtk_list_store_append(store, &iter); 00321 gtk_list_store_set(store, &iter, 0, _("Lower Left"), -1); 00322 gtk_list_store_set(store, &iter, 1, 0, -1); 00323 gtk_list_store_append(store, &iter); 00324 gtk_list_store_set(store, &iter, 0, _("Lower Middle"), -1); 00325 gtk_list_store_set(store, &iter, 1, 3, -1); 00326 gtk_list_store_append(store, &iter); 00327 gtk_list_store_set(store, &iter, 0, _("Lower Right"), -1); 00328 gtk_list_store_set(store, &iter, 1, 6, -1); 00329 00330 return store; 00331 } 00332 00333 /* we reuse the color menu so we need to declare it */ 00334 static GtkWidget *create_color_menu(GSCHEM_TOPLEVEL * w_current); 00335 00341 void text_edit_dialog_ok(GtkWidget *w, GSCHEM_TOPLEVEL *w_current) 00342 { 00343 int len=0; 00344 int text_size=8; 00345 char *text_string = NULL; 00346 char *text_size_string = NULL; 00347 int new_text_alignment; 00348 int num_selected; 00349 GtkTextBuffer *textbuffer; 00350 GtkTextIter start, end; 00351 GtkWidget *widget; 00352 00353 num_selected = g_list_length( geda_list_get_glist( w_current->toplevel->page_current->selection_list )); 00354 00355 /* text string entry will only show up if one object is selected */ 00356 if (num_selected == 1) { 00357 widget = g_object_get_data (G_OBJECT (w_current->tewindow), "textentry"); 00358 textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(widget)); 00359 gtk_text_buffer_get_bounds (textbuffer, &start, &end); 00360 text_string = gtk_text_iter_get_text (&start, &end); 00361 } /* else the string will be null which is okay */ 00362 00363 widget = g_object_get_data (G_OBJECT (w_current->tewindow), "sizeentry"); 00364 text_size_string = (char *) gtk_entry_get_text(GTK_ENTRY(widget)); 00365 00366 if (text_string) { 00367 len = strlen(text_string); 00368 } 00369 00370 if (text_size_string) { 00371 text_size = atoi(text_size_string); 00372 } 00373 00374 if (text_size == 0) { 00375 text_size = default_text_size; 00376 } 00377 00378 new_text_alignment = w_current->text_alignment; 00379 00380 o_text_edit_end(w_current, text_string, len, text_size, new_text_alignment); 00381 } 00382 00389 void text_edit_dialog_response(GtkWidget * widget, gint response, GSCHEM_TOPLEVEL *w_current) 00390 { 00391 switch(response) { 00392 case GTK_RESPONSE_ACCEPT: 00393 text_edit_dialog_ok(widget, w_current); 00394 break; 00395 case GTK_RESPONSE_REJECT: 00396 case GTK_RESPONSE_DELETE_EVENT: 00397 /* void */ 00398 break; 00399 default: 00400 printf("text_edit_dialog_response(): strange signal %d\n", response); 00401 } 00402 /* clean up */ 00403 i_set_state(w_current, SELECT); 00404 i_update_toolbar(w_current); 00405 gtk_widget_destroy(w_current->tewindow); 00406 w_current->tewindow = NULL; 00407 } 00408 00415 void text_edit_dialog (GSCHEM_TOPLEVEL *w_current, const char *string, int text_size, 00416 int text_alignment) 00417 { 00418 GtkWidget *label; 00419 GtkWidget *table; 00420 GtkWidget *vbox; 00421 GtkWidget *optionmenu; 00422 GtkWidget *combobox; 00423 GtkListStore *align_menu_model; 00424 GtkCellRenderer *cell; 00425 GtkWidget *viewport1; 00426 GtkWidget *textentry; 00427 GtkWidget *sizeentry; 00428 GtkWidget *alignment; 00429 GtkWidget *scrolled_window; 00430 GtkTextBuffer *textbuffer; 00431 char *text_size_string; 00432 int num_selected; 00433 /* Lookup table for quickly translating between alignment values and the 00434 combo box list indices, index is alignment value, value is list index */ 00435 static int alignment_lookup[] = {6, 3, 0, 7, 4, 1, 8, 5, 2}; 00436 00437 if (!w_current->tewindow) { 00438 w_current->tewindow = gschem_dialog_new_with_buttons(_("Edit Text Properties"), 00439 GTK_WINDOW(w_current->main_window), 00440 GTK_DIALOG_MODAL, 00441 "text-edit", w_current, 00442 GTK_STOCK_CANCEL, 00443 GTK_RESPONSE_REJECT, 00444 GTK_STOCK_OK, 00445 GTK_RESPONSE_ACCEPT, 00446 NULL); 00447 00448 /* Set the alternative button order (ok, cancel, help) for other systems */ 00449 gtk_dialog_set_alternative_button_order(GTK_DIALOG(w_current->tewindow), 00450 GTK_RESPONSE_ACCEPT, 00451 GTK_RESPONSE_REJECT, 00452 -1); 00453 00454 gtk_dialog_set_default_response(GTK_DIALOG(w_current->tewindow), 00455 GTK_RESPONSE_ACCEPT); 00456 00457 g_signal_connect (G_OBJECT (w_current->tewindow), "response", 00458 G_CALLBACK (text_edit_dialog_response), 00459 w_current); 00460 00461 gtk_window_position(GTK_WINDOW (w_current->tewindow), 00462 GTK_WIN_POS_MOUSE); 00463 00464 00465 vbox = GTK_DIALOG(w_current->tewindow)->vbox; 00466 gtk_container_set_border_width(GTK_CONTAINER(w_current->tewindow),DIALOG_BORDER_SPACING); 00467 gtk_box_set_spacing(GTK_BOX(vbox), DIALOG_V_SPACING); 00468 00469 /* add a text box if only one object is selected */ 00470 num_selected = g_list_length( geda_list_get_glist( w_current->toplevel->page_current->selection_list )); 00471 00472 if (num_selected == 1) { 00473 label = gtk_label_new (_("<b>Text Content</b>")); 00474 gtk_label_set_use_markup (GTK_LABEL (label), TRUE); 00475 gtk_misc_set_alignment(GTK_MISC(label),0,0); 00476 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); 00477 00478 alignment = gtk_alignment_new(0,0,1,1); 00479 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 00480 DIALOG_INDENTATION, 0); 00481 gtk_box_pack_start(GTK_BOX(vbox), alignment, TRUE, TRUE, 0); 00482 00483 viewport1 = gtk_viewport_new (NULL, NULL); 00484 gtk_widget_set_size_request(GTK_WIDGET(viewport1),-1,75); 00485 00486 scrolled_window = gtk_scrolled_window_new(NULL, NULL); 00487 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled_window), 00488 GTK_POLICY_AUTOMATIC, 00489 GTK_POLICY_AUTOMATIC); 00490 gtk_container_add (GTK_CONTAINER (viewport1), scrolled_window); 00491 gtk_container_add( GTK_CONTAINER(alignment), viewport1); 00492 00493 textentry = gtk_text_view_new(); 00494 gtk_text_view_set_editable (GTK_TEXT_VIEW (textentry), TRUE); 00495 if (string != NULL) { 00496 textbuffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (textentry)); 00497 gtk_text_buffer_set_text (GTK_TEXT_BUFFER (textbuffer), string, -1); 00498 select_all_text_in_textview (GTK_TEXT_VIEW (textentry)); 00499 } 00500 00502 /* See first the code in text_input_dialog and get it working before adding it here. */ 00503 00504 gtk_container_add(GTK_CONTAINER(scrolled_window), textentry); 00505 gtk_widget_grab_focus(textentry); 00506 GLADE_HOOKUP_OBJECT(w_current->tewindow, textentry,"textentry"); 00507 } 00508 00509 label = gtk_label_new(_("<b>Text Properties</b>")); 00510 gtk_label_set_use_markup(GTK_LABEL(label), TRUE); 00511 gtk_misc_set_alignment(GTK_MISC(label),0,0); 00512 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); 00513 00514 alignment = gtk_alignment_new(0,0,1,1); 00515 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 00516 DIALOG_INDENTATION, 0); 00517 gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, FALSE, 0); 00518 00519 table = gtk_table_new (3, 2, FALSE); 00520 gtk_table_set_row_spacings(GTK_TABLE(table), DIALOG_V_SPACING); 00521 gtk_table_set_col_spacings(GTK_TABLE(table), DIALOG_H_SPACING); 00522 gtk_container_add(GTK_CONTAINER(alignment), table); 00523 00524 label = gtk_label_new(_("Color:")); 00525 gtk_misc_set_alignment(GTK_MISC(label),0,0); 00526 gtk_table_attach(GTK_TABLE(table), label, 0,1,0,1, GTK_FILL,0,0,0); 00527 00528 optionmenu = create_color_menu (w_current); 00529 gtk_table_attach_defaults(GTK_TABLE(table), optionmenu, 1,2,0,1); 00530 00531 label = gtk_label_new(_("Size:")); 00532 gtk_misc_set_alignment(GTK_MISC(label),0,0); 00533 gtk_table_attach(GTK_TABLE(table), label, 0,1,1,2, GTK_FILL,0,0,0); 00534 00535 sizeentry = gtk_entry_new_with_max_length (10); 00536 gtk_editable_select_region(GTK_EDITABLE (sizeentry), 0, -1); 00537 gtk_table_attach_defaults(GTK_TABLE(table), sizeentry, 1,2,1,2); 00538 gtk_entry_set_activates_default(GTK_ENTRY(sizeentry), TRUE); 00539 00540 label = gtk_label_new(_("Alignment:")); 00541 gtk_misc_set_alignment(GTK_MISC(label),0,0); 00542 gtk_table_attach(GTK_TABLE(table), label, 0,1,2,3, GTK_FILL,0,0,0); 00543 00544 align_menu_model = create_menu_alignment(w_current); 00545 combobox = gtk_combo_box_new_with_model(GTK_TREE_MODEL(align_menu_model)); 00546 gtk_combo_box_set_wrap_width(GTK_COMBO_BOX(combobox), 3); 00547 cell = gtk_cell_renderer_text_new(); 00548 gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combobox), cell, TRUE); 00549 gtk_cell_layout_set_attributes(GTK_CELL_LAYOUT(combobox), cell, 00550 "text", 0, NULL); 00551 gtk_combo_box_set_active(GTK_COMBO_BOX(combobox), 00552 alignment_lookup[text_alignment]); 00553 w_current->text_alignment = text_alignment; 00554 g_object_unref (align_menu_model); 00555 gtk_table_attach_defaults(GTK_TABLE(table), combobox, 1,2,2,3); 00556 g_signal_connect(G_OBJECT(combobox), "changed", 00557 G_CALLBACK(change_alignment), w_current); 00558 00559 GLADE_HOOKUP_OBJECT(w_current->tewindow, sizeentry,"sizeentry"); 00560 gtk_widget_show_all(w_current->tewindow); 00561 } 00562 00563 else { /* dialog already there */ 00564 gtk_window_present(GTK_WINDOW(w_current->tewindow)); 00565 } 00566 00567 text_size_string = g_strdup_printf("%d", text_size); 00568 sizeentry = g_object_get_data (G_OBJECT (w_current->tewindow), "sizeentry"); 00569 gtk_entry_set_text(GTK_ENTRY(sizeentry), 00570 text_size_string); 00571 g_free(text_size_string); 00572 } 00573 00574 /***************** End of Text Edit dialog box ************************/ 00575 00576 /***************** Start of Line Type/width dialog box ****************/ 00577 00582 static GtkWidget *create_menu_linetype (GSCHEM_TOPLEVEL *w_current) 00583 { 00584 GtkWidget *menu; 00585 GSList *group; 00586 struct line_type { 00587 gchar *str; 00588 OBJECT_TYPE type; 00589 } types[] = { { N_("Solid"), TYPE_SOLID }, 00590 { N_("Dotted"), TYPE_DOTTED }, 00591 { N_("Dashed"), TYPE_DASHED }, 00592 { N_("Center"), TYPE_CENTER }, 00593 { N_("Phantom"), TYPE_PHANTOM }, 00594 { N_("*unchanged*"), TYPE_ERASE } }; 00595 gint i; 00596 00597 menu = gtk_menu_new (); 00598 group = NULL; 00599 00600 for (i = 0; i < sizeof (types) / sizeof (struct line_type); i++) { 00601 GtkWidget *menuitem; 00602 00603 menuitem = gtk_radio_menu_item_new_with_label (group, _(types[i].str)); 00604 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem)); 00605 gtk_menu_append (GTK_MENU (menu), menuitem); 00606 gtk_object_set_data (GTK_OBJECT(menuitem), "linetype", 00607 GINT_TO_POINTER (types[i].type)); 00608 gtk_widget_show (menuitem); 00609 } 00610 00611 return(menu); 00612 } 00613 00627 static gboolean selection_get_line_type(GList *selection, 00628 OBJECT_END *end, OBJECT_TYPE *type, 00629 gint *width, gint *length, gint *space) 00630 { 00631 GList *iter; 00632 OBJECT *object; 00633 gboolean found = FALSE; 00634 OBJECT_END oend; 00635 OBJECT_TYPE otype; 00636 gint owidth, olength, ospace; 00637 00638 for (iter = selection; iter != NULL; iter = g_list_next(iter)) { 00639 object = (OBJECT *) iter->data; 00640 if (! o_get_line_options(object, &oend, &otype, 00641 &owidth, &olength, &ospace)) 00642 continue; 00643 00644 if (found == FALSE) { /* first object with filltype */ 00645 found = TRUE; 00646 *end = oend; 00647 *type = otype; 00648 *width = owidth; 00649 *length = olength; 00650 *space = ospace; 00651 } else { 00652 /* indicate different values with the value -2 */ 00653 if (*end != oend) *end = -2; 00654 if (*type != otype) *type = -2; 00655 if (*width != owidth) *width = -2; 00656 if (*length != olength) *length = -2; 00657 if (*space != ospace) *space = -2; 00658 } 00659 } 00660 00661 return found; 00662 } 00663 00664 00676 static void line_type_dialog_set_values(struct line_type_data *line_type_data, 00677 OBJECT_END end, OBJECT_TYPE type, 00678 gint width, gint length, gint space) 00679 { 00680 gchar *text; 00681 GtkWidget *menu, *menuitem; 00682 00683 if (type == -2) 00684 type = TYPE_ERASE; 00685 gtk_option_menu_set_history(GTK_OPTION_MENU(line_type_data->line_type), type); 00686 menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(line_type_data->line_type)); 00687 menuitem = gtk_menu_get_active(GTK_MENU(menu)); 00688 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE); 00689 00690 if (width == -2) 00691 text = g_strdup(_("*unchanged*")); 00692 else 00693 text = g_strdup_printf ("%d", width); 00694 gtk_entry_set_text (GTK_ENTRY (line_type_data->width_entry), text); 00695 gtk_entry_select_region (GTK_ENTRY (line_type_data->width_entry), 00696 0, strlen (text)); 00697 g_free(text); 00698 00699 if (length == -2) 00700 text = g_strdup(_("*unchanged*")); 00701 else 00702 text = g_strdup_printf ("%d", length); 00703 gtk_entry_set_text (GTK_ENTRY (line_type_data->length_entry), text); 00704 gtk_entry_select_region (GTK_ENTRY (line_type_data->length_entry), 00705 0, strlen (text)); 00706 g_free(text); 00707 00708 if (space == -2) 00709 text = g_strdup(_("*unchanged*")); 00710 else 00711 text = g_strdup_printf ("%d", space); 00712 gtk_entry_set_text (GTK_ENTRY (line_type_data->space_entry), text); 00713 gtk_entry_select_region (GTK_ENTRY (line_type_data->space_entry), 00714 0, strlen (text)); 00715 g_free(text); 00716 } 00717 00718 00724 static gint line_type_dialog_linetype_change(GtkWidget *w, gpointer data) 00725 { 00726 struct line_type_data *line_type_data = (struct line_type_data*) data; 00727 GtkWidget *menuitem; 00728 gboolean activate_length_entry, activate_space_entry; 00729 gint type; 00730 00731 menuitem = gtk_menu_get_active ( 00732 GTK_MENU (gtk_option_menu_get_menu ( 00733 GTK_OPTION_MENU (line_type_data->line_type)))); 00734 00735 type = GPOINTER_TO_INT( 00736 gtk_object_get_data (GTK_OBJECT (menuitem), "linetype")); 00737 switch(type) { 00738 case(TYPE_SOLID): 00739 activate_length_entry = FALSE; 00740 activate_space_entry = FALSE; 00741 break; 00742 case(TYPE_DOTTED): 00743 activate_length_entry = FALSE; 00744 activate_space_entry = TRUE; 00745 break; 00746 case(TYPE_DASHED): 00747 case(TYPE_CENTER): 00748 case(TYPE_PHANTOM): 00749 activate_length_entry = TRUE; 00750 activate_space_entry = TRUE; 00751 break; 00752 default: 00753 activate_length_entry = TRUE; 00754 activate_space_entry = TRUE; 00755 } 00756 00757 gtk_widget_set_sensitive (line_type_data->space_entry, 00758 activate_space_entry); 00759 gtk_widget_set_sensitive (line_type_data->length_entry, 00760 activate_length_entry); 00761 00762 return(0); 00763 } 00764 00765 00771 static void line_type_dialog_ok(GtkWidget *w, gpointer data) 00772 { 00773 struct line_type_data *line_type_data = (struct line_type_data*)data; 00774 GSCHEM_TOPLEVEL *w_current = line_type_data->w_current; 00775 TOPLEVEL *toplevel = w_current->toplevel; 00776 GList *selection, *iter; 00777 OBJECT *object; 00778 const gchar *width_str, *length_str, *space_str; 00779 OBJECT_TYPE type; 00780 gint width, length, space; 00781 OBJECT_TYPE otype; 00782 OBJECT_END oend; 00783 gint owidth, olength, ospace; 00784 00785 /* get the selection */ 00786 if (! o_select_selected(w_current)) 00787 return; 00788 selection = 00789 geda_list_get_glist(w_current->toplevel->page_current->selection_list); 00790 00791 /* get the new values from the text entries of the dialog */ 00792 width_str = gtk_entry_get_text (GTK_ENTRY ( 00793 line_type_data->width_entry)); 00794 length_str = gtk_entry_get_text (GTK_ENTRY ( 00795 line_type_data->length_entry)); 00796 space_str = gtk_entry_get_text (GTK_ENTRY ( 00797 line_type_data->space_entry)); 00798 type = GPOINTER_TO_INT( 00799 gtk_object_get_data ( 00800 GTK_OBJECT ( 00801 gtk_menu_get_active ( 00802 GTK_MENU (gtk_option_menu_get_menu ( 00803 GTK_OPTION_MENU ( 00804 line_type_data->line_type))))), "linetype")); 00805 if (type == TYPE_ERASE) 00806 type = -1; 00807 00808 /* convert the options to integers (-1 means unchanged) */ 00809 width = g_utf8_collate (g_utf8_casefold (width_str, -1), 00810 g_utf8_casefold (_("*unchanged*"), -1)) 00811 ? atoi (width_str) : -1; 00812 length = g_utf8_collate (g_utf8_casefold (length_str, -1), 00813 g_utf8_casefold (_("*unchanged*"), -1)) 00814 ? atoi (length_str) : -1; 00815 space = g_utf8_collate (g_utf8_casefold (space_str, -1), 00816 g_utf8_casefold (_("*unchanged*"), -1)) 00817 ? atoi (space_str) : -1; 00818 00819 for (iter = selection; iter != NULL; iter = g_list_next(iter)) { 00820 object = (OBJECT *) iter->data; 00821 if (! o_get_line_options(object, &oend, &otype, 00822 &owidth, &olength, &ospace)) 00823 continue; 00824 00825 /* oend is not in the dialog, yet */ 00826 otype = type == -1 ? otype : type; 00827 owidth = width == -1 ? owidth : width; 00828 olength = length == -1 ? olength : length; 00829 ospace = space == -1 ? ospace : space; 00830 00831 /* set all not required options to -1 and 00832 set nice parameters if not provided by the user */ 00833 switch (otype) { 00834 case (TYPE_SOLID): 00835 olength = ospace = -1; 00836 break; 00837 case (TYPE_DOTTED): 00838 olength = -1; 00839 if (ospace < 1) ospace = 100; 00840 break; 00841 case (TYPE_DASHED): 00842 case (TYPE_CENTER): 00843 case (TYPE_PHANTOM): 00844 if (ospace < 1) ospace = 100; 00845 if (olength < 1) olength = 100; 00846 break; 00847 default: 00848 g_assert_not_reached(); 00849 } 00850 00851 o_set_line_options (toplevel, object, 00852 oend, otype, owidth, olength, ospace); 00853 } 00854 00855 toplevel->page_current->CHANGED = 1; 00856 o_undo_savestate(w_current, UNDO_ALL); 00857 } 00858 00865 void line_type_dialog_response(GtkWidget *widget, gint response, 00866 struct line_type_data *line_type_data) 00867 { 00868 switch (response) { 00869 case GTK_RESPONSE_REJECT: 00870 case GTK_RESPONSE_DELETE_EVENT: 00871 /* void */ 00872 break; 00873 case GTK_RESPONSE_ACCEPT: 00874 line_type_dialog_ok(widget, line_type_data); 00875 break; 00876 default: 00877 printf("line_type_dialog_response(): strange signal %d\n",response); 00878 } 00879 00880 i_set_state (line_type_data->w_current, SELECT); 00881 i_update_toolbar (line_type_data->w_current); 00882 gtk_widget_destroy (line_type_data->dialog); 00883 00884 g_free (line_type_data); 00885 } 00886 00892 void line_type_dialog (GSCHEM_TOPLEVEL *w_current) 00893 { 00894 GtkWidget *dialog; 00895 GtkWidget *vbox; 00896 GtkWidget *optionmenu = NULL; 00897 GtkWidget *length_entry = NULL; 00898 GtkWidget *space_entry = NULL; 00899 GtkWidget *width_entry = NULL; 00900 GtkWidget *table; 00901 GtkWidget *label; 00902 struct line_type_data *line_type_data; 00903 GList *selection; 00904 OBJECT_END end=END_NONE; 00905 OBJECT_TYPE type=TYPE_SOLID; 00906 gint width=1, length=-1, space=-1; 00907 00908 if (! o_select_selected(w_current)) 00909 return; 00910 00911 selection = 00912 geda_list_get_glist(w_current->toplevel->page_current->selection_list); 00913 00914 if (! selection_get_line_type(selection, &end, &type, 00915 &width, &length, &space)) 00916 return; 00917 00918 line_type_data = (struct line_type_data*) g_malloc ( 00919 sizeof (struct line_type_data)); 00920 00921 dialog = gschem_dialog_new_with_buttons(_("Edit Line Width & Type"), 00922 GTK_WINDOW(w_current->main_window), 00923 GTK_DIALOG_MODAL, 00924 "line-type", w_current, 00925 GTK_STOCK_CANCEL, 00926 GTK_RESPONSE_REJECT, 00927 GTK_STOCK_OK, 00928 GTK_RESPONSE_ACCEPT, 00929 NULL); 00930 00931 /* Set the alternative button order (ok, cancel, help) for other systems */ 00932 gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), 00933 GTK_RESPONSE_ACCEPT, 00934 GTK_RESPONSE_REJECT, 00935 -1); 00936 00937 gtk_window_position(GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); 00938 00939 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_ACCEPT); 00940 00941 g_signal_connect (G_OBJECT (dialog), "response", 00942 G_CALLBACK (line_type_dialog_response), 00943 line_type_data); 00944 00945 gtk_container_border_width(GTK_CONTAINER(dialog), 00946 DIALOG_BORDER_SPACING); 00947 vbox = GTK_DIALOG(dialog)->vbox; 00948 gtk_box_set_spacing(GTK_BOX(vbox), DIALOG_V_SPACING); 00949 00950 /* Don't know whether to set the headline or not (Werner) */ 00951 /* label = gtk_label_new(_("Line Properties:")); 00952 gtk_misc_set_alignment(GTK_MISC(label),0,0); 00953 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); */ 00954 00955 table = gtk_table_new (4, 2, FALSE); 00956 gtk_table_set_row_spacings(GTK_TABLE(table), DIALOG_V_SPACING); 00957 gtk_table_set_col_spacings(GTK_TABLE(table), DIALOG_H_SPACING); 00958 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); 00959 00960 label = gtk_label_new (_("Type:")); 00961 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 00962 gtk_table_attach(GTK_TABLE(table), label, 0,1,0,1, GTK_FILL,0,0,0); 00963 00964 label = gtk_label_new (_("Width:")); 00965 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 00966 gtk_table_attach(GTK_TABLE(table), label, 0,1,1,2, GTK_FILL,0,0,0); 00967 00968 label = gtk_label_new (_("Dash Length:")); 00969 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 00970 gtk_table_attach(GTK_TABLE(table), label, 0,1,2,3, GTK_FILL,0,0,0); 00971 00972 label = gtk_label_new (_("Dash Space:")); 00973 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 00974 gtk_table_attach(GTK_TABLE(table), label, 0,1,3,4, GTK_FILL,0,0,0); 00975 00976 optionmenu = gtk_option_menu_new (); 00977 gtk_option_menu_set_menu(GTK_OPTION_MENU(optionmenu), 00978 create_menu_linetype (w_current)); 00979 gtk_table_attach_defaults(GTK_TABLE(table), optionmenu, 00980 1,2,0,1); 00981 00982 width_entry = gtk_entry_new(); 00983 gtk_entry_set_activates_default (GTK_ENTRY(width_entry), TRUE); 00984 gtk_editable_select_region(GTK_EDITABLE(width_entry), 0, -1); 00985 gtk_table_attach_defaults(GTK_TABLE(table), width_entry, 00986 1,2,1,2); 00987 00988 g_signal_connect(G_OBJECT (optionmenu), "changed", 00989 G_CALLBACK (line_type_dialog_linetype_change), 00990 line_type_data); 00991 00992 length_entry = gtk_entry_new(); 00993 gtk_entry_set_activates_default (GTK_ENTRY(length_entry), TRUE); 00994 gtk_editable_select_region(GTK_EDITABLE(length_entry), 0, -1); 00995 gtk_table_attach_defaults(GTK_TABLE(table), length_entry, 00996 1,2,2,3); 00997 00998 space_entry = gtk_entry_new(); 00999 gtk_entry_set_activates_default (GTK_ENTRY(space_entry), TRUE); 01000 gtk_editable_select_region(GTK_EDITABLE(space_entry), 0, -1); 01001 gtk_table_attach_defaults(GTK_TABLE(table), space_entry, 01002 1,2,3,4); 01003 01004 /* populate the data structure */ 01005 line_type_data->dialog = dialog; 01006 line_type_data->width_entry = width_entry; 01007 line_type_data->line_type = optionmenu; 01008 line_type_data->length_entry = length_entry; 01009 line_type_data->space_entry = space_entry; 01010 01011 line_type_data->w_current = w_current; 01012 01013 /* fill in the fields of the dialog */ 01014 line_type_dialog_set_values(line_type_data, end, type, 01015 width, length, space); 01016 01017 /* calling it once will set the dash space/length activity */ 01018 line_type_dialog_linetype_change(optionmenu, line_type_data); 01019 01020 gtk_widget_grab_focus(width_entry); 01021 gtk_widget_show_all (dialog); 01022 } 01023 01024 /***************** End of Line Type / Width dialog box ****************/ 01025 01026 /***************** Start of Fill Type dialog box **********************/ 01027 01032 static GtkWidget *create_menu_filltype (GSCHEM_TOPLEVEL *w_current) 01033 { 01034 GtkWidget *menu; 01035 GSList *group; 01036 struct fill_type { 01037 gchar *str; 01038 OBJECT_FILLING type; 01039 } types[] = { { N_("Hollow"), FILLING_HOLLOW }, 01040 { N_("Filled"), FILLING_FILL }, 01041 { N_("Mesh"), FILLING_MESH }, 01042 { N_("Hatch"), FILLING_HATCH }, 01043 { N_("*unchanged*"), FILLING_VOID } }; 01044 gint i; 01045 01046 menu = gtk_menu_new (); 01047 group = NULL; 01048 01049 for (i = 0; i < sizeof (types) / sizeof (struct fill_type); i++) { 01050 GtkWidget *menuitem; 01051 01052 menuitem = gtk_radio_menu_item_new_with_label (group, _(types[i].str)); 01053 group = gtk_radio_menu_item_group (GTK_RADIO_MENU_ITEM (menuitem)); 01054 gtk_menu_append (GTK_MENU (menu), menuitem); 01055 gtk_object_set_data (GTK_OBJECT(menuitem), "filltype", 01056 GINT_TO_POINTER (types[i].type)); 01057 gtk_widget_show (menuitem); 01058 } 01059 01060 return menu; 01061 } 01062 01077 static gboolean selection_get_fill_type(GList *selection, 01078 OBJECT_FILLING *type, gint *width, 01079 gint *pitch1, gint *angle1, 01080 gint *pitch2, gint *angle2) 01081 { 01082 GList *iter; 01083 OBJECT *object; 01084 gboolean found = FALSE; 01085 OBJECT_FILLING otype; 01086 gint owidth, opitch1, oangle1, opitch2, oangle2; 01087 01088 01089 for (iter = selection; iter != NULL; iter = g_list_next(iter)) { 01090 object = (OBJECT *) iter->data; 01091 if (! o_get_fill_options(object, &otype, &owidth, 01092 &opitch1, &oangle1, &opitch2, &oangle2)) 01093 continue; 01094 01095 if (found == FALSE) { /* first object with filltype */ 01096 found = TRUE; 01097 *type = otype; 01098 *width = owidth; 01099 *pitch1 = opitch1; 01100 *angle1 = oangle1; 01101 *pitch2 = opitch2; 01102 *angle2 = oangle2; 01103 } else { 01104 /* indicate different values with the value -2 */ 01105 if (*type != otype) *type = -2; 01106 if (*width != owidth) *width = -2; 01107 if (*pitch1 != opitch1) *pitch1 = -2; 01108 if (*angle1 != oangle1) *angle1 = -2; 01109 if (*pitch2 != opitch2) *pitch2 = -2; 01110 if (*angle2 != oangle2) *angle2 = -2; 01111 } 01112 } 01113 01114 return found; 01115 } 01116 01117 01130 static void fill_type_dialog_set_values(struct fill_type_data *fill_type_data, 01131 OBJECT_FILLING type, gint width, 01132 gint pitch1, gint angle1, 01133 gint pitch2, gint angle2) 01134 { 01135 gchar *text; 01136 GtkWidget *menu, *menuitem; 01137 01138 if (type == -2) 01139 type = FILLING_VOID; 01140 gtk_option_menu_set_history(GTK_OPTION_MENU(fill_type_data->fill_type), type); 01141 menu = gtk_option_menu_get_menu(GTK_OPTION_MENU(fill_type_data->fill_type)); 01142 menuitem = gtk_menu_get_active(GTK_MENU(menu)); 01143 gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(menuitem), TRUE); 01144 01145 if (width == -2) 01146 text = g_strdup(_("*unchanged*")); 01147 else 01148 text = g_strdup_printf ("%d", width); 01149 gtk_entry_set_text (GTK_ENTRY (fill_type_data->width_entry), text); 01150 gtk_entry_select_region (GTK_ENTRY (fill_type_data->width_entry), 01151 0, strlen (text)); 01152 g_free(text); 01153 01154 if (pitch1 == -2) 01155 text = g_strdup(_("*unchanged*")); 01156 else 01157 text = g_strdup_printf ("%d", pitch1); 01158 gtk_entry_set_text (GTK_ENTRY (fill_type_data->pitch1_entry), text); 01159 gtk_entry_select_region (GTK_ENTRY (fill_type_data->pitch1_entry), 01160 0, strlen (text)); 01161 g_free(text); 01162 01163 if (angle1 == -2) 01164 text = g_strdup(_("*unchanged*")); 01165 else 01166 text = g_strdup_printf ("%d", angle1); 01167 gtk_entry_set_text (GTK_ENTRY (fill_type_data->angle1_entry), text); 01168 gtk_entry_select_region (GTK_ENTRY (fill_type_data->angle1_entry), 01169 0, strlen (text)); 01170 g_free(text); 01171 01172 if (pitch2 == -2) 01173 text = g_strdup(_("*unchanged*")); 01174 else 01175 text = g_strdup_printf ("%d", pitch2); 01176 gtk_entry_set_text (GTK_ENTRY (fill_type_data->pitch2_entry), text); 01177 gtk_entry_select_region (GTK_ENTRY (fill_type_data->pitch2_entry), 01178 0, strlen (text)); 01179 g_free(text); 01180 01181 if (angle2 == -2) 01182 text = g_strdup(_("*unchanged*")); 01183 else 01184 text = g_strdup_printf ("%d", angle2); 01185 gtk_entry_set_text (GTK_ENTRY (fill_type_data->angle2_entry), text); 01186 gtk_entry_select_region (GTK_ENTRY (fill_type_data->angle2_entry), 01187 0, strlen (text)); 01188 g_free(text); 01189 } 01190 01191 01197 static gint fill_type_dialog_filltype_change(GtkWidget *w, gpointer data) 01198 { 01199 struct fill_type_data *fill_type_data = (struct fill_type_data*) data; 01200 GtkWidget *menuitem; 01201 gboolean activate_width_entry; 01202 gboolean activate_anglepitch1_entries; 01203 gboolean activate_anglepitch2_entries; 01204 gint type; 01205 01206 menuitem = gtk_menu_get_active ( 01207 GTK_MENU (gtk_option_menu_get_menu ( 01208 GTK_OPTION_MENU (fill_type_data->fill_type)))); 01209 01210 type = GPOINTER_TO_INT( 01211 gtk_object_get_data (GTK_OBJECT (menuitem), "filltype")); 01212 switch(type) { 01213 case(FILLING_HOLLOW): 01214 case(FILLING_FILL): 01215 activate_width_entry = FALSE; 01216 activate_anglepitch1_entries = FALSE; 01217 activate_anglepitch2_entries = FALSE; 01218 break; 01219 case(FILLING_HATCH): 01220 activate_width_entry = TRUE; 01221 activate_anglepitch1_entries = TRUE; 01222 activate_anglepitch2_entries = FALSE; 01223 break; 01224 case(FILLING_MESH): 01225 case(FILLING_VOID): 01226 activate_width_entry = TRUE; 01227 activate_anglepitch1_entries = TRUE; 01228 activate_anglepitch2_entries = TRUE; 01229 break; 01230 default: 01231 g_assert_not_reached (); 01232 } 01233 01234 gtk_widget_set_sensitive (fill_type_data->width_entry, 01235 activate_width_entry); 01236 gtk_widget_set_sensitive (fill_type_data->angle1_entry, 01237 activate_anglepitch1_entries); 01238 gtk_widget_set_sensitive (fill_type_data->pitch1_entry, 01239 activate_anglepitch1_entries); 01240 gtk_widget_set_sensitive (fill_type_data->angle2_entry, 01241 activate_anglepitch2_entries); 01242 gtk_widget_set_sensitive (fill_type_data->pitch2_entry, 01243 activate_anglepitch2_entries); 01244 01245 return(0); 01246 } 01247 01253 static void fill_type_dialog_ok(GtkWidget *w, gpointer data) 01254 { 01255 struct fill_type_data *fill_type_data = (struct fill_type_data*) data; 01256 GSCHEM_TOPLEVEL *w_current = fill_type_data->w_current; 01257 TOPLEVEL *toplevel = w_current->toplevel; 01258 GList *selection, *iter; 01259 OBJECT *object; 01260 const gchar *width_str, *angle1_str, *pitch1_str, *angle2_str, *pitch2_str; 01261 OBJECT_FILLING type; 01262 gint width, angle1, pitch1, angle2, pitch2; 01263 OBJECT_FILLING otype; 01264 gint owidth, oangle1, opitch1, oangle2, opitch2; 01265 01266 /* get the selection */ 01267 if (! o_select_selected(w_current)) 01268 return; 01269 selection = 01270 geda_list_get_glist(w_current->toplevel->page_current->selection_list); 01271 01272 /* get the new values from the text entries of the dialog */ 01273 width_str = gtk_entry_get_text (GTK_ENTRY ( 01274 fill_type_data->width_entry)); 01275 angle1_str = gtk_entry_get_text (GTK_ENTRY ( 01276 fill_type_data->angle1_entry)); 01277 pitch1_str = gtk_entry_get_text (GTK_ENTRY ( 01278 fill_type_data->pitch1_entry)); 01279 angle2_str = gtk_entry_get_text (GTK_ENTRY ( 01280 fill_type_data->angle2_entry)); 01281 pitch2_str = gtk_entry_get_text (GTK_ENTRY ( 01282 fill_type_data->pitch2_entry)); 01283 type = GPOINTER_TO_INT( 01284 gtk_object_get_data ( 01285 GTK_OBJECT ( 01286 gtk_menu_get_active ( 01287 GTK_MENU (gtk_option_menu_get_menu ( 01288 GTK_OPTION_MENU ( 01289 fill_type_data->fill_type))))), "filltype")); 01290 if (type == FILLING_VOID) 01291 type = -1; 01292 01293 /* convert the options to integers (-1 means unchanged) */ 01294 width = g_utf8_collate (g_utf8_casefold (width_str, -1), 01295 g_utf8_casefold(_("*unchanged*"), -1)) 01296 ? atoi (width_str) : -1; 01297 angle1 = g_utf8_collate (g_utf8_casefold (angle1_str, -1), 01298 g_utf8_casefold (_("*unchanged*"), -1)) 01299 ? atoi (angle1_str) : -1; 01300 pitch1 = g_utf8_collate (g_utf8_casefold (pitch1_str, -1), 01301 g_utf8_casefold (_("*unchanged*"), -1)) 01302 ? atoi (pitch1_str) : -1; 01303 angle2 = g_utf8_collate (g_utf8_casefold (angle2_str, -1), 01304 g_utf8_casefold (_("*unchanged*"), -1)) 01305 ? atoi (angle2_str) : -1; 01306 pitch2 = g_utf8_collate (g_utf8_casefold (pitch2_str, -1), 01307 g_utf8_casefold(_("*unchanged*"), -1)) 01308 ? atoi (pitch2_str) : -1; 01309 01310 for (iter = selection; iter != NULL; iter = g_list_next(iter)) { 01311 object = (OBJECT *) iter->data; 01312 if (! o_get_fill_options(object, &otype, &owidth, 01313 &opitch1, &oangle1, &opitch2, &oangle2)) 01314 continue; 01315 01316 otype = type == -1 ? otype : type; 01317 owidth = width == -1 ? owidth : width; 01318 opitch1 = pitch1 == -1 ? opitch1 : pitch1; 01319 oangle1 = angle1 == -1 ? oangle1 : angle1; 01320 opitch2 = pitch2 == -1 ? opitch2 : pitch2; 01321 oangle2 = angle2 == -1 ? oangle2 : angle2; 01322 01323 /* set all not required options to -1 and 01324 set nice parameters if not provided by the user */ 01325 switch (otype) { 01326 case (FILLING_HOLLOW): 01327 case (FILLING_FILL): 01328 owidth = opitch1 = oangle1 = opitch2 = oangle2 = -1; 01329 break; 01330 case (FILLING_HATCH): 01331 if (owidth < 1) owidth = 1; 01332 if (opitch1 < 1) opitch1 = 100; 01333 opitch2 = oangle2 = -1; 01334 break; 01335 case (FILLING_MESH): 01336 if (owidth < 1) owidth = 1; 01337 if (opitch1 < 1) opitch1 = 100; 01338 if (opitch2 < 1) opitch2 = 100; 01339 break; 01340 default: 01341 g_assert_not_reached(); 01342 } 01343 01344 o_set_fill_options (toplevel, object, otype, owidth, 01345 opitch1, oangle1, opitch2, oangle2); 01346 } 01347 01348 toplevel->page_current->CHANGED = 1; 01349 o_undo_savestate(w_current, UNDO_ALL); 01350 } 01351 01357 void fill_type_dialog_response(GtkWidget *widget, gint response, 01358 struct fill_type_data *fill_type_data) 01359 { 01360 switch (response) { 01361 case GTK_RESPONSE_REJECT: 01362 case GTK_RESPONSE_DELETE_EVENT: 01363 /* void */ 01364 break; 01365 case GTK_RESPONSE_ACCEPT: 01366 fill_type_dialog_ok(widget, fill_type_data); 01367 break; 01368 default: 01369 printf("line_type_dialog_response(): strange signal %d\n",response); 01370 } 01371 01372 i_set_state (fill_type_data->w_current, SELECT); 01373 i_update_toolbar (fill_type_data->w_current); 01374 01375 gtk_grab_remove (fill_type_data->dialog); 01376 gtk_widget_destroy (fill_type_data->dialog); 01377 01378 g_free (fill_type_data); 01379 } 01380 01386 void fill_type_dialog(GSCHEM_TOPLEVEL *w_current) 01387 { 01388 GtkWidget *dialog; 01389 GtkWidget *vbox; 01390 GtkWidget *optionmenu = NULL; 01391 GtkWidget *width_entry = NULL; 01392 GtkWidget *angle1_entry = NULL; 01393 GtkWidget *pitch1_entry = NULL; 01394 GtkWidget *angle2_entry = NULL; 01395 GtkWidget *pitch2_entry = NULL; 01396 GtkWidget *label; 01397 GtkWidget *table; 01398 struct fill_type_data *fill_type_data; 01399 GList *selection; 01400 OBJECT_FILLING type=FILLING_VOID; 01401 gint width=0, pitch1=0, angle1=0, pitch2=0, angle2=0; 01402 01403 if (! o_select_selected(w_current)) 01404 return; 01405 01406 selection = 01407 geda_list_get_glist(w_current->toplevel->page_current->selection_list); 01408 01409 if (! selection_get_fill_type(selection, &type, &width, 01410 &pitch1, &angle1, &pitch2, &angle2)) 01411 return; 01412 01413 fill_type_data = (struct fill_type_data*) g_malloc ( 01414 sizeof (struct fill_type_data)); 01415 01416 dialog = gschem_dialog_new_with_buttons(_("Edit Fill Type"), 01417 GTK_WINDOW(w_current->main_window), 01418 GTK_DIALOG_MODAL, 01419 "fill-type", w_current, 01420 GTK_STOCK_CANCEL, 01421 GTK_RESPONSE_REJECT, 01422 GTK_STOCK_OK, 01423 GTK_RESPONSE_ACCEPT, 01424 NULL); 01425 01426 /* Set the alternative button order (ok, cancel, help) for other systems */ 01427 gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), 01428 GTK_RESPONSE_ACCEPT, 01429 GTK_RESPONSE_REJECT, 01430 -1); 01431 01432 gtk_window_position(GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); 01433 01434 gtk_dialog_set_default_response(GTK_DIALOG(dialog), 01435 GTK_RESPONSE_ACCEPT); 01436 01437 g_signal_connect (G_OBJECT (dialog), "response", 01438 G_CALLBACK (fill_type_dialog_response), 01439 fill_type_data); 01440 01441 gtk_container_border_width(GTK_CONTAINER(dialog), DIALOG_BORDER_SPACING); 01442 vbox = GTK_DIALOG(dialog)->vbox; 01443 gtk_box_set_spacing(GTK_BOX(vbox), DIALOG_V_SPACING); 01444 01445 /* Don't know whether to use the headline or not (Werner) */ 01446 /* label = gtk_label_new(_("Fill Properties:")); 01447 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 01448 gtk_box_pack_start(GTK_BOX(vbox),label, FALSE, FALSE, 0); */ 01449 01450 table = gtk_table_new (6, 2, FALSE); 01451 gtk_table_set_row_spacings(GTK_TABLE(table), DIALOG_V_SPACING); 01452 gtk_table_set_col_spacings(GTK_TABLE(table), DIALOG_H_SPACING); 01453 gtk_box_pack_start(GTK_BOX(vbox), table, FALSE, FALSE, 0); 01454 01455 label = gtk_label_new (_("Fill Type:")); 01456 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 01457 gtk_table_attach(GTK_TABLE(table), label, 0,1,0,1, GTK_FILL,0,0,0); 01458 01459 label = gtk_label_new (_("Line Width:")); 01460 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 01461 gtk_table_attach(GTK_TABLE(table), label, 0,1,1,2, GTK_FILL,0,0,0); 01462 01463 label = gtk_label_new (_("Angle 1:")); 01464 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 01465 gtk_table_attach(GTK_TABLE(table), label, 0,1,2,3, GTK_FILL,0,0,0); 01466 01467 label = gtk_label_new (_("Pitch 1:")); 01468 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 01469 gtk_table_attach(GTK_TABLE(table), label, 0,1,3,4, GTK_FILL,0,0,0); 01470 01471 label = gtk_label_new (_("Angle 2:")); 01472 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 01473 gtk_table_attach(GTK_TABLE(table), label, 0,1,4,5, GTK_FILL,0,0,0); 01474 01475 label = gtk_label_new (_("Pitch 2:")); 01476 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 01477 gtk_table_attach(GTK_TABLE(table), label, 0,1,5,6, GTK_FILL,0,0,0); 01478 01479 01480 optionmenu = gtk_option_menu_new (); 01481 gtk_option_menu_set_menu(GTK_OPTION_MENU(optionmenu), 01482 create_menu_filltype (w_current)); 01483 gtk_table_attach_defaults(GTK_TABLE(table), optionmenu, 01484 1,2,0,1); 01485 01486 g_signal_connect (G_OBJECT (optionmenu), "changed", 01487 G_CALLBACK (fill_type_dialog_filltype_change), 01488 fill_type_data); 01489 01490 width_entry = gtk_entry_new(); 01491 gtk_entry_set_activates_default (GTK_ENTRY(width_entry), TRUE); 01492 gtk_table_attach_defaults(GTK_TABLE(table), width_entry, 01493 1,2,1,2); 01494 01495 angle1_entry = gtk_entry_new (); 01496 gtk_entry_set_activates_default (GTK_ENTRY(angle1_entry), TRUE); 01497 gtk_table_attach_defaults(GTK_TABLE(table), angle1_entry, 01498 1,2,2,3); 01499 01500 pitch1_entry = gtk_entry_new (); 01501 gtk_entry_set_activates_default (GTK_ENTRY(pitch1_entry), TRUE); 01502 gtk_table_attach_defaults(GTK_TABLE(table), pitch1_entry, 01503 1,2,3,4); 01504 01505 angle2_entry = gtk_entry_new (); 01506 gtk_entry_set_activates_default (GTK_ENTRY(angle2_entry), TRUE); 01507 gtk_table_attach_defaults(GTK_TABLE(table), angle2_entry, 01508 1,2,4,5); 01509 01510 pitch2_entry = gtk_entry_new (); 01511 gtk_entry_set_activates_default (GTK_ENTRY(pitch2_entry), TRUE); 01512 gtk_table_attach_defaults(GTK_TABLE(table), pitch2_entry, 01513 1,2,5,6); 01514 01515 /* populate the data structure */ 01516 fill_type_data->dialog = dialog; 01517 fill_type_data->fill_type = optionmenu; 01518 fill_type_data->width_entry = width_entry; 01519 fill_type_data->angle1_entry = angle1_entry; 01520 fill_type_data->pitch1_entry = pitch1_entry; 01521 fill_type_data->angle2_entry = angle2_entry; 01522 fill_type_data->pitch2_entry = pitch2_entry; 01523 01524 fill_type_data->w_current = w_current; 01525 01526 /* fill in the fields of the dialog */ 01527 fill_type_dialog_set_values(fill_type_data, type, width, 01528 pitch1, angle1, pitch2, angle2); 01529 01530 /* Set the widget activity according to the current filltype */ 01531 fill_type_dialog_filltype_change(optionmenu, fill_type_data); 01532 01533 gtk_widget_grab_focus(width_entry); 01534 gtk_widget_show_all (dialog); 01535 } 01536 01537 /***************** End of Fill Type dialog box ***********************/ 01538 01539 /***************** Start of Arc dialog box ***************************/ 01540 01547 void arc_angle_dialog_response(GtkWidget *w, gint response, 01548 GSCHEM_TOPLEVEL *w_current) 01549 { 01550 GtkWidget *spinentry; 01551 gint radius, start_angle, sweep_angle; 01552 OBJECT *arc_object = NULL; 01553 01554 switch (response) { 01555 case GTK_RESPONSE_REJECT: 01556 case GTK_RESPONSE_DELETE_EVENT: 01557 /* void */ 01558 break; 01559 case GTK_RESPONSE_ACCEPT: 01560 spinentry = g_object_get_data(G_OBJECT(w_current->aawindow),"radius"); 01561 radius = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spinentry)); 01562 spinentry = g_object_get_data(G_OBJECT(w_current->aawindow),"spin_start"); 01563 start_angle = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spinentry)); 01564 spinentry = g_object_get_data(G_OBJECT(w_current->aawindow),"spin_sweep"); 01565 sweep_angle = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spinentry)); 01566 arc_object = (OBJECT*) g_object_get_data(G_OBJECT(w_current->aawindow),"arc_object"); 01567 01568 if (arc_object != NULL) { 01569 o_arc_modify(w_current->toplevel, arc_object, radius, 0, ARC_RADIUS); 01570 o_arc_modify(w_current->toplevel, arc_object, start_angle, 0, ARC_START_ANGLE); 01571 o_arc_modify(w_current->toplevel, arc_object, sweep_angle, 0, ARC_END_ANGLE); 01572 } else { 01573 o_arc_end4(w_current, radius, start_angle, sweep_angle); 01574 } 01575 break; 01576 default: 01577 printf("arc_angle_dialog_response(): strange signal %d\n",response); 01578 } 01579 01580 gtk_widget_destroy(w_current->aawindow); 01581 w_current->aawindow = NULL; 01582 } 01583 01594 void arc_angle_dialog (GSCHEM_TOPLEVEL *w_current, OBJECT *arc_object) 01595 { 01596 GtkWidget *label = NULL; 01597 GtkWidget *vbox; 01598 GtkWidget *alignment, *table; 01599 GtkWidget *radius, *spin_start, *spin_sweep; 01600 01601 if (!w_current->aawindow) { 01602 w_current->aawindow = gschem_dialog_new_with_buttons(_("Arc Params"), 01603 GTK_WINDOW(w_current->main_window), 01604 GTK_DIALOG_MODAL, 01605 "arc-angle", w_current, 01606 GTK_STOCK_CANCEL, 01607 GTK_RESPONSE_REJECT, 01608 GTK_STOCK_OK, 01609 GTK_RESPONSE_ACCEPT, 01610 NULL); 01611 01612 /* Set the alternative button order (ok, cancel, help) for other systems */ 01613 gtk_dialog_set_alternative_button_order(GTK_DIALOG(w_current->aawindow), 01614 GTK_RESPONSE_ACCEPT, 01615 GTK_RESPONSE_REJECT, 01616 -1); 01617 01618 gtk_window_position(GTK_WINDOW(w_current->aawindow), 01619 GTK_WIN_POS_MOUSE); 01620 01621 g_signal_connect (G_OBJECT (w_current->aawindow), "response", 01622 G_CALLBACK (arc_angle_dialog_response), 01623 w_current); 01624 01625 gtk_dialog_set_default_response(GTK_DIALOG(w_current->aawindow), 01626 GTK_RESPONSE_ACCEPT); 01627 01628 gtk_container_border_width(GTK_CONTAINER(w_current->aawindow), DIALOG_BORDER_SPACING); 01629 vbox = GTK_DIALOG(w_current->aawindow)->vbox; 01630 gtk_box_set_spacing(GTK_BOX(vbox), DIALOG_V_SPACING); 01631 01632 01633 alignment = gtk_alignment_new(0,0,1,1); 01634 gtk_alignment_set_padding(GTK_ALIGNMENT(alignment), 0, 0, 01635 0 /*DIALOG_INDENTATION */, 0); 01636 gtk_box_pack_start(GTK_BOX(vbox), alignment, FALSE, FALSE, 0); 01637 01638 table = gtk_table_new (2, 3, FALSE); 01639 gtk_table_set_row_spacings(GTK_TABLE(table), DIALOG_V_SPACING); 01640 gtk_table_set_col_spacings(GTK_TABLE(table), DIALOG_H_SPACING); 01641 gtk_container_add(GTK_CONTAINER(alignment), table); 01642 01643 label = gtk_label_new (_("Arc Radius:")); 01644 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 01645 gtk_table_attach(GTK_TABLE(table), label, 0,1,0,1, GTK_FILL,0,0,0); 01646 01647 radius = gtk_spin_button_new_with_range(1, 100000, 100); 01648 gtk_entry_set_activates_default(GTK_ENTRY(radius), TRUE); 01649 gtk_table_attach_defaults(GTK_TABLE(table), radius, 1,2,0,1); 01650 01651 label = gtk_label_new (_("Start Angle:")); 01652 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 01653 gtk_table_attach(GTK_TABLE(table), label, 0,1,1,2, GTK_FILL,0,0,0); 01654 01655 spin_start = gtk_spin_button_new_with_range(-360,360,1); 01656 gtk_entry_set_activates_default(GTK_ENTRY(spin_start), TRUE); 01657 gtk_table_attach_defaults(GTK_TABLE(table), spin_start, 1,2,1,2); 01658 01659 label = gtk_label_new(_("Degrees of Sweep:")); 01660 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 01661 gtk_table_attach(GTK_TABLE(table), label, 0,1,2,3, GTK_FILL,0,0,0); 01662 01663 spin_sweep = gtk_spin_button_new_with_range(-360,360,1); 01664 gtk_entry_set_activates_default(GTK_ENTRY(spin_sweep), TRUE); 01665 gtk_table_attach_defaults(GTK_TABLE(table), spin_sweep, 1,2,2,3); 01666 01667 GLADE_HOOKUP_OBJECT(w_current->aawindow, radius, "radius"); 01668 GLADE_HOOKUP_OBJECT(w_current->aawindow, spin_start,"spin_start"); 01669 GLADE_HOOKUP_OBJECT(w_current->aawindow, spin_sweep,"spin_sweep"); 01670 g_object_set_data(G_OBJECT(w_current->aawindow), "arc_object", arc_object); 01671 gtk_widget_show_all (w_current->aawindow); 01672 } 01673 01674 else { /* dialog already created */ 01675 gtk_window_present (GTK_WINDOW(w_current->aawindow)); 01676 radius = g_object_get_data(G_OBJECT(w_current->aawindow),"radius"); 01677 spin_start = g_object_get_data(G_OBJECT(w_current->aawindow),"spin_start"); 01678 spin_sweep = g_object_get_data(G_OBJECT(w_current->aawindow),"spin_sweep"); 01679 } 01680 01681 if (arc_object == NULL) { 01682 gtk_spin_button_set_value(GTK_SPIN_BUTTON(radius), w_current->distance); 01683 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_start),0); 01684 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_sweep), 90); 01685 } else { 01686 gtk_spin_button_set_value(GTK_SPIN_BUTTON(radius), 01687 arc_object->arc->width / 2); 01688 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_start), 01689 arc_object->arc->start_angle); 01690 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_sweep), 01691 arc_object->arc->end_angle); 01692 } 01693 01694 gtk_widget_grab_focus(radius); 01695 } 01696 01697 /***************** End of Arc dialog box *****************************/ 01698 01699 /***************** Start of Translate dialog box *********************/ 01700 01706 void translate_dialog_response(GtkWidget *widget, gint response, 01707 GSCHEM_TOPLEVEL *w_current) 01708 { 01709 GtkWidget *textentry; 01710 gchar *string; 01711 01712 switch (response) { 01713 case GTK_RESPONSE_REJECT: 01714 case GTK_RESPONSE_DELETE_EVENT: 01715 /* void */ 01716 break; 01717 case GTK_RESPONSE_ACCEPT: 01718 textentry = g_object_get_data(G_OBJECT(w_current->trwindow),"textentry"); 01719 string = (gchar*) gtk_entry_get_text(GTK_ENTRY(textentry)); 01720 if (strlen(string) != 0) { 01721 o_complex_translate_all(w_current, atoi(string)); 01722 } 01723 break; 01724 default: 01725 printf("translate_edit_dialog_response(): strange signal %d\n",response); 01726 } 01727 01728 i_set_state(w_current, SELECT); 01729 i_update_toolbar(w_current); 01730 gtk_widget_destroy(w_current->trwindow); 01731 w_current->trwindow=NULL; 01732 } 01733 01734 01739 void translate_dialog (GSCHEM_TOPLEVEL *w_current) 01740 { 01741 GtkWidget *label; 01742 GtkWidget *textentry; 01743 GtkWidget *vbox; 01744 01745 if (!w_current->trwindow) { 01746 w_current->trwindow = gschem_dialog_new_with_buttons(_("Translate"), 01747 GTK_WINDOW(w_current->main_window), 01748 GTK_DIALOG_MODAL, 01749 "translate", w_current, 01750 GTK_STOCK_CANCEL, 01751 GTK_RESPONSE_REJECT, 01752 GTK_STOCK_OK, 01753 GTK_RESPONSE_ACCEPT, 01754 NULL); 01755 01756 /* Set the alternative button order (ok, cancel, help) for other systems */ 01757 gtk_dialog_set_alternative_button_order(GTK_DIALOG(w_current->trwindow), 01758 GTK_RESPONSE_ACCEPT, 01759 GTK_RESPONSE_REJECT, 01760 -1); 01761 01762 gtk_window_position(GTK_WINDOW (w_current->trwindow), 01763 GTK_WIN_POS_MOUSE); 01764 01765 g_signal_connect (G_OBJECT (w_current->trwindow), "response", 01766 G_CALLBACK (translate_dialog_response), 01767 w_current); 01768 01769 gtk_dialog_set_default_response(GTK_DIALOG(w_current->trwindow), 01770 GTK_RESPONSE_ACCEPT); 01771 01772 gtk_container_border_width(GTK_CONTAINER(w_current->trwindow), 01773 DIALOG_BORDER_SPACING); 01774 vbox = GTK_DIALOG(w_current->trwindow)->vbox; 01775 gtk_box_set_spacing(GTK_BOX(vbox), DIALOG_V_SPACING); 01776 01777 label = gtk_label_new(_("Offset to translate?\n(0 for origin)")); 01778 gtk_misc_set_alignment(GTK_MISC (label), 0, 0); 01779 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); 01780 01781 textentry = gtk_entry_new_with_max_length (10); 01782 gtk_entry_set_text(GTK_ENTRY(textentry), "0"); 01783 gtk_editable_select_region(GTK_EDITABLE(textentry), 0, -1); 01784 gtk_entry_set_activates_default(GTK_ENTRY(textentry), TRUE); 01785 gtk_box_pack_start(GTK_BOX(vbox),textentry, FALSE, FALSE, 0); 01786 01787 GLADE_HOOKUP_OBJECT(w_current->trwindow, textentry, "textentry"); 01788 gtk_widget_show_all (w_current->trwindow); 01789 } 01790 01791 else { /* dialog already created */ 01792 gtk_window_present(GTK_WINDOW(w_current->trwindow)); 01793 } 01794 } 01795 01796 /***************** End of Translate dialog box ***********************/ 01797 01798 /***************** Start of Text size dialog box *********************/ 01799 01804 void text_size_dialog_response(GtkWidget *w, gint response, 01805 GSCHEM_TOPLEVEL *w_current) 01806 { 01807 GtkWidget *spin_size; 01808 gint size; 01809 01810 switch (response) { 01811 case GTK_RESPONSE_ACCEPT: 01812 spin_size = g_object_get_data(G_OBJECT(w_current->tswindow),"spin_size"); 01813 size = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spin_size)); 01814 01815 w_current->text_size = size; 01816 w_current->toplevel->page_current->CHANGED=1; 01817 o_undo_savestate(w_current, UNDO_ALL); 01818 break; 01819 case GTK_RESPONSE_REJECT: 01820 case GTK_RESPONSE_DELETE_EVENT: 01821 /* void */ 01822 break; 01823 default: 01824 printf("text_size_dialog_response(): strange signal %d\n",response); 01825 } 01826 01827 /* clean up */ 01828 i_set_state(w_current, SELECT); 01829 i_update_toolbar(w_current); 01830 gtk_widget_destroy(w_current->tswindow); 01831 w_current->tswindow = NULL; 01832 } 01833 01838 void text_size_dialog (GSCHEM_TOPLEVEL *w_current) 01839 { 01840 GtkWidget *label = NULL; 01841 GtkWidget *vbox; 01842 GtkWidget *spin_size; 01843 01844 if (!w_current->tswindow) { 01845 w_current->tswindow = gschem_dialog_new_with_buttons(_("Text Size"), 01846 GTK_WINDOW(w_current->main_window), 01847 GTK_DIALOG_MODAL, 01848 "text-size", w_current, 01849 GTK_STOCK_CANCEL, 01850 GTK_RESPONSE_REJECT, 01851 GTK_STOCK_OK, 01852 GTK_RESPONSE_ACCEPT, 01853 NULL); 01854 01855 /* Set the alternative button order (ok, cancel, help) for other systems */ 01856 gtk_dialog_set_alternative_button_order(GTK_DIALOG(w_current->tswindow), 01857 GTK_RESPONSE_ACCEPT, 01858 GTK_RESPONSE_REJECT, 01859 -1); 01860 01861 gtk_window_position(GTK_WINDOW(w_current->tswindow), 01862 GTK_WIN_POS_MOUSE); 01863 01864 g_signal_connect (G_OBJECT (w_current->tswindow), "response", 01865 G_CALLBACK (text_size_dialog_response), 01866 w_current); 01867 gtk_dialog_set_default_response(GTK_DIALOG(w_current->tswindow), 01868 GTK_RESPONSE_ACCEPT); 01869 01870 gtk_container_border_width(GTK_CONTAINER(w_current->tswindow), 01871 DIALOG_BORDER_SPACING); 01872 vbox = GTK_DIALOG(w_current->tswindow)->vbox; 01873 gtk_box_set_spacing(GTK_BOX(vbox), DIALOG_V_SPACING); 01874 01875 label = gtk_label_new (_("Enter new text size:")); 01876 gtk_misc_set_alignment (GTK_MISC (label), 0, 0); 01877 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); 01878 01879 spin_size = gtk_spin_button_new_with_range(2,10000,2); 01880 gtk_editable_select_region( GTK_EDITABLE(spin_size), 0, -1); 01881 gtk_box_pack_start(GTK_BOX(vbox), spin_size, FALSE, FALSE, 0); 01882 gtk_entry_set_activates_default(GTK_ENTRY(spin_size), TRUE); 01883 gtk_widget_grab_focus(spin_size); 01884 01885 GLADE_HOOKUP_OBJECT(w_current->tswindow, spin_size, "spin_size"); 01886 gtk_widget_show_all(w_current->tswindow); 01887 } 01888 01889 else { /* dialog already created */ 01890 gtk_window_present(GTK_WINDOW(w_current->tswindow)); 01891 } 01892 01893 /* always set the current text size to the dialog */ 01894 spin_size = g_object_get_data(G_OBJECT(w_current->tswindow),"spin_size"); 01895 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_size), w_current->text_size); 01896 gtk_editable_select_region(GTK_EDITABLE(spin_size), 0, -1); 01897 } 01898 01899 /***************** End of Text size dialog box ***********************/ 01900 01901 /***************** Start of Snap size dialog box *********************/ 01902 01908 void snap_size_dialog_response(GtkWidget *w, gint response, 01909 GSCHEM_TOPLEVEL *w_current) 01910 { 01911 GtkWidget *spin_size; 01912 gint size; 01913 01914 switch (response) { 01915 case GTK_RESPONSE_ACCEPT: 01916 spin_size = g_object_get_data(G_OBJECT(w_current->tswindow),"spin_size"); 01917 size = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON(spin_size)); 01918 01919 w_current->snap_size = size; 01920 i_update_grid_info (w_current); 01921 o_invalidate_all (w_current); 01922 w_current->toplevel->page_current->CHANGED=1; /* maybe remove those two lines */ 01923 o_undo_savestate(w_current, UNDO_ALL); 01924 break; 01925 case GTK_RESPONSE_REJECT: 01926 case GTK_RESPONSE_DELETE_EVENT: 01927 /* void */ 01928 break; 01929 default: 01930 printf("snap_size_dialog_response(): strange signal %d\n",response); 01931 } 01932 01933 /* clean up */ 01934 i_set_state(w_current, SELECT); 01935 i_update_toolbar(w_current); 01936 gtk_widget_destroy(w_current->tswindow); 01937 w_current->tswindow = NULL; 01938 } 01939 01944 void snap_size_dialog (GSCHEM_TOPLEVEL *w_current) 01945 { 01946 GtkWidget *label = NULL; 01947 GtkWidget *vbox; 01948 GtkWidget *spin_size; 01949 01950 if (!w_current->tswindow) { 01951 w_current->tswindow = gschem_dialog_new_with_buttons(_("Snap Size"), 01952 GTK_WINDOW(w_current->main_window), 01953 GTK_DIALOG_MODAL, 01954 "snap-size", w_current, 01955 GTK_STOCK_CANCEL, 01956 GTK_RESPONSE_REJECT, 01957 GTK_STOCK_OK, 01958 GTK_RESPONSE_ACCEPT, 01959 NULL); 01960 01961 /* Set the alternative button order (ok, cancel, help) for other systems */ 01962 gtk_dialog_set_alternative_button_order(GTK_DIALOG(w_current->tswindow), 01963 GTK_RESPONSE_ACCEPT, 01964 GTK_RESPONSE_REJECT, 01965 -1); 01966 01967 gtk_window_position(GTK_WINDOW(w_current->tswindow), 01968 GTK_WIN_POS_MOUSE); 01969 01970 g_signal_connect (G_OBJECT (w_current->tswindow), "response", 01971 G_CALLBACK (snap_size_dialog_response), 01972 w_current); 01973 gtk_dialog_set_default_response(GTK_DIALOG(w_current->tswindow), 01974 GTK_RESPONSE_ACCEPT); 01975 01976 gtk_container_border_width(GTK_CONTAINER(w_current->tswindow), 01977 DIALOG_BORDER_SPACING); 01978 vbox = GTK_DIALOG(w_current->tswindow)->vbox; 01979 gtk_box_set_spacing(GTK_BOX(vbox), DIALOG_V_SPACING); 01980 01981 label = gtk_label_new (_("Enter new snap grid spacing:")); 01982 gtk_misc_set_alignment (GTK_MISC (label), 0, 0); 01983 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); 01984 01985 spin_size = gtk_spin_button_new_with_range(0,100000,5); 01986 gtk_editable_select_region( GTK_EDITABLE(spin_size), 0, -1); 01987 gtk_box_pack_start(GTK_BOX(vbox), spin_size, FALSE, FALSE, 0); 01988 gtk_entry_set_activates_default(GTK_ENTRY(spin_size), TRUE); 01989 gtk_widget_grab_focus(spin_size); 01990 01991 GLADE_HOOKUP_OBJECT(w_current->tswindow, spin_size, "spin_size"); 01992 gtk_widget_show_all(w_current->tswindow); 01993 } 01994 01995 else { /* dialog already there */ 01996 gtk_window_present(GTK_WINDOW(w_current->tswindow)); 01997 } 01998 01999 /* always set the current gschem value to the dialog entry */ 02000 spin_size = g_object_get_data(G_OBJECT(w_current->tswindow),"spin_size"); 02001 gtk_spin_button_set_value(GTK_SPIN_BUTTON(spin_size), w_current->snap_size); 02002 gtk_editable_select_region(GTK_EDITABLE(spin_size), 0, -1); 02003 } 02004 02005 /***************** End of Snap size dialog box ***********************/ 02006 02007 /***************** Start of slot edit dialog box *********************/ 02008 02014 void slot_edit_dialog_response(GtkWidget *widget, gint response, GSCHEM_TOPLEVEL *w_current) 02015 { 02016 GtkWidget *textentry; 02017 char *slot_string; 02018 int len; 02019 gchar *string = NULL; 02020 02021 switch (response) { 02022 case GTK_RESPONSE_REJECT: 02023 case GTK_RESPONSE_DELETE_EVENT: 02024 /* void */ 02025 break; 02026 case GTK_RESPONSE_ACCEPT: 02027 textentry = g_object_get_data(G_OBJECT(w_current->sewindow),"textentry"); 02028 string = (gchar*) gtk_entry_get_text(GTK_ENTRY(textentry)); 02029 len = strlen(string); 02030 if (len != 0) { 02031 slot_string = g_strdup_printf ("slot=%s", string); 02032 o_slot_end (w_current, o_select_return_first_object (w_current), 02033 slot_string); 02034 g_free (slot_string); 02035 } 02036 break; 02037 default: 02038 printf("slot_edit_dialog_response(): strange signal %d\n",response); 02039 } 02040 i_set_state(w_current, SELECT); 02041 i_update_toolbar(w_current); 02042 gtk_widget_destroy(w_current->sewindow); 02043 w_current->sewindow = NULL; 02044 } 02045 02046 02051 void slot_edit_dialog (GSCHEM_TOPLEVEL *w_current, const char *string) 02052 { 02053 GtkWidget *label = NULL; 02054 GtkWidget *textentry; 02055 GtkWidget *vbox; 02056 02057 if (!w_current->sewindow) { 02058 w_current->sewindow = gschem_dialog_new_with_buttons(_("Edit slot number"), 02059 GTK_WINDOW(w_current->main_window), 02060 GTK_DIALOG_MODAL, 02061 "slot-edit", w_current, 02062 GTK_STOCK_CANCEL, 02063 GTK_RESPONSE_REJECT, 02064 GTK_STOCK_OK, 02065 GTK_RESPONSE_ACCEPT, 02066 NULL); 02067 02068 /* Set the alternative button order (ok, cancel, help) for other systems */ 02069 gtk_dialog_set_alternative_button_order(GTK_DIALOG(w_current->sewindow), 02070 GTK_RESPONSE_ACCEPT, 02071 GTK_RESPONSE_REJECT, 02072 -1); 02073 02074 gtk_window_position(GTK_WINDOW(w_current->sewindow), 02075 GTK_WIN_POS_MOUSE); 02076 02077 gtk_dialog_set_default_response (GTK_DIALOG (w_current->sewindow), 02078 GTK_RESPONSE_ACCEPT); 02079 02080 g_signal_connect (G_OBJECT (w_current->sewindow), "response", 02081 G_CALLBACK (slot_edit_dialog_response), 02082 w_current); 02083 02084 gtk_container_border_width(GTK_CONTAINER(w_current->sewindow), 02085 DIALOG_BORDER_SPACING); 02086 vbox = GTK_DIALOG(w_current->sewindow)->vbox; 02087 gtk_box_set_spacing(GTK_BOX(vbox), DIALOG_V_SPACING); 02088 02089 label = gtk_label_new (_("Edit slot number:")); 02090 gtk_misc_set_alignment(GTK_MISC(label),0,0); 02091 gtk_box_pack_start(GTK_BOX (vbox), label, FALSE, FALSE, 0); 02092 02093 textentry = gtk_entry_new(); 02094 gtk_box_pack_start( GTK_BOX(vbox), 02095 textentry, FALSE, FALSE, 0); 02096 gtk_entry_set_max_length(GTK_ENTRY(textentry), 80); 02097 gtk_entry_set_activates_default (GTK_ENTRY(textentry),TRUE); 02098 02099 GLADE_HOOKUP_OBJECT(w_current->sewindow, textentry, "textentry"); 02100 gtk_widget_show_all (w_current->sewindow); 02101 } 02102 02103 else { /* dialog already created */ 02104 gtk_window_present (GTK_WINDOW(w_current->sewindow)); 02105 } 02106 02107 /* always set the current text and select the number of the slot */ 02108 if (string != NULL) { 02109 textentry = g_object_get_data(G_OBJECT(w_current->sewindow),"textentry"); 02110 gtk_entry_set_text(GTK_ENTRY(textentry), string); 02111 gtk_editable_select_region (GTK_EDITABLE(textentry), 0, -1); 02112 } 02113 } 02114 02115 /***************** End of Slot Edit dialog box ***********************/ 02116 02117 /***************** Start of help/about dialog box ********************/ 02118 02123 void about_dialog (GSCHEM_TOPLEVEL *w_current) 02124 { 02125 char *version_string; 02126 char *logo_file; 02127 GdkPixbuf *logo; 02128 GError *error = NULL; 02129 02130 version_string = g_strdup_printf (_("%s (g%.7s)"), 02131 PACKAGE_DOTTED_VERSION, 02132 PACKAGE_GIT_COMMIT); 02133 02134 logo_file = g_strconcat (w_current->toplevel->bitmap_directory, 02135 G_DIR_SEPARATOR_S, "gschem-about-logo.png", NULL); 02136 02137 logo = gdk_pixbuf_new_from_file (logo_file, &error); 02138 g_free (logo_file); 02139 02140 if (error != NULL) { 02141 g_assert (logo == NULL); 02142 s_log_message ("Could not load image at file: %s\n%s\n", 02143 logo_file, error->message); 02144 g_error_free (error); 02145 } 02146 02147 gtk_show_about_dialog ( 02148 GTK_WINDOW (w_current->main_window), 02149 "version", version_string, 02150 "logo", logo, 02151 "title", _("About gschem"), 02152 "comments", _("gEDA: GPL Electronic Design Automation"), 02153 "copyright", 02154 /* TRANSLATORS: "ChangeLog" is a literal filename; please don't translate it. */ 02155 _("Copyright © 1998-2012 Ales Hvezda" 02156 " <ahvezda@geda.seul.org>\n" 02157 "Copyright © 1998-2012 gEDA Contributors" 02158 " (see ChangeLog for details)"), 02159 "website", "http://www.gpleda.org/", 02160 NULL); 02161 02162 g_free (version_string); 02163 g_object_unref (logo); 02164 } 02165 02166 /***************** End of help/about dialog box *********************/ 02167 02168 /***************** Start of coord dialog box ************************/ 02173 void coord_dialog_response(GtkWidget *w, gint response, GSCHEM_TOPLEVEL *w_current) 02174 { 02175 gtk_widget_destroy(w_current->cowindow); 02176 w_current->cowindow = NULL; 02177 w_current->coord_world = NULL; 02178 w_current->coord_screen = NULL; 02179 } 02180 02186 void coord_display_update(GSCHEM_TOPLEVEL *w_current, int x, int y) 02187 { 02188 char *string; 02189 int world_x, world_y; 02190 02191 string = g_strdup_printf("(%d, %d)", x, y); 02192 gtk_label_set_text(GTK_LABEL(w_current->coord_screen), string ); 02193 g_free(string); 02194 02195 SCREENtoWORLD (w_current, x, y, &world_x, &world_y); 02196 world_x = snap_grid (w_current, world_x); 02197 world_y = snap_grid (w_current, world_y); 02198 02199 string = g_strdup_printf("(%d, %d)", world_x, world_y); 02200 gtk_label_set_text(GTK_LABEL(w_current->coord_world), string ); 02201 g_free(string); 02202 } 02203 02208 void coord_dialog (GSCHEM_TOPLEVEL *w_current, int x, int y) 02209 { 02210 GtkWidget *frame; 02211 GtkWidget *vbox; 02212 02213 if (!w_current->cowindow) { 02214 w_current->cowindow = gschem_dialog_new_with_buttons(_("Coords"), 02215 GTK_WINDOW(w_current->main_window), 02216 0, /* Not modal GTK_DIALOG_MODAL */ 02217 "coord", w_current, 02218 GTK_STOCK_CLOSE, 02219 GTK_RESPONSE_REJECT, 02220 NULL); 02221 02222 gtk_window_position (GTK_WINDOW (w_current->cowindow), 02223 GTK_WIN_POS_NONE); 02224 02225 g_signal_connect (G_OBJECT (w_current->cowindow), "response", 02226 G_CALLBACK (coord_dialog_response), 02227 w_current); 02228 02229 gtk_container_border_width (GTK_CONTAINER(w_current->cowindow), 02230 DIALOG_BORDER_SPACING); 02231 vbox = GTK_DIALOG(w_current->cowindow)->vbox; 02232 gtk_box_set_spacing(GTK_BOX(vbox), DIALOG_V_SPACING); 02233 02234 02235 frame = gtk_frame_new (_("Screen")); 02236 w_current->coord_screen = gtk_label_new("(########, ########)"); 02237 gtk_label_set_justify( GTK_LABEL(w_current->coord_screen), GTK_JUSTIFY_LEFT); 02238 gtk_misc_set_padding(GTK_MISC(w_current->coord_screen), 02239 DIALOG_H_SPACING, DIALOG_V_SPACING); 02240 gtk_container_add(GTK_CONTAINER (frame), 02241 w_current->coord_screen); 02242 gtk_box_pack_start(GTK_BOX (vbox), frame, FALSE, FALSE, 0); 02243 02244 frame = gtk_frame_new (_("World")); 02245 w_current->coord_world = gtk_label_new ("(########, ########)"); 02246 gtk_misc_set_padding(GTK_MISC(w_current->coord_world), 02247 DIALOG_H_SPACING, DIALOG_V_SPACING); 02248 gtk_label_set_justify(GTK_LABEL(w_current->coord_world), 02249 GTK_JUSTIFY_LEFT); 02250 gtk_container_add(GTK_CONTAINER (frame), 02251 w_current->coord_world); 02252 gtk_box_pack_start(GTK_BOX (vbox), frame, FALSE, FALSE, 0); 02253 02254 gtk_widget_show_all(w_current->cowindow); 02255 } 02256 02257 else { /* window already creatad */ 02258 gtk_window_present(GTK_WINDOW(w_current->cowindow)); 02259 } 02260 02261 /* always update the coords when the dialog is requested */ 02262 coord_display_update(w_current, x, y); 02263 } 02264 02265 /***************** End of coord dialog box **************************/ 02266 02267 /***************** Start of color edit dialog box *******************/ 02268 02277 char *index2functionstring(int index) 02278 { 02279 char *string; 02280 02281 switch(index) { 02282 case(BACKGROUND_COLOR): 02283 string = g_strdup (_("Background")); 02284 break; 02285 case(PIN_COLOR): 02286 string = g_strdup (_("Pin")); 02287 break; 02288 case(NET_ENDPOINT_COLOR): 02289 string = g_strdup (_("Net endpoint")); 02290 break; 02291 case(GRAPHIC_COLOR): 02292 string = g_strdup (_("Graphic")); 02293 break; 02294 case(NET_COLOR): 02295 string = g_strdup (_("Net")); 02296 break; 02297 case(ATTRIBUTE_COLOR): 02298 string = g_strdup (_("Attribute")); 02299 break; 02300 case(LOGIC_BUBBLE_COLOR): 02301 string = g_strdup (_("Logic bubble")); 02302 break; 02303 case(DOTS_GRID_COLOR): 02304 string = g_strdup (_("Grid point")); 02305 break; 02306 case(DETACHED_ATTRIBUTE_COLOR): 02307 string = g_strdup (_("Detached attribute")); 02308 break; 02309 case(TEXT_COLOR): 02310 string = g_strdup (_("Text")); 02311 break; 02312 case(BUS_COLOR): 02313 string = g_strdup (_("Bus")); 02314 break; 02315 case(SELECT_COLOR): 02316 string = g_strdup (_("Selection")); 02317 break; 02318 case(BOUNDINGBOX_COLOR): 02319 string = g_strdup (_("Bounding box")); 02320 break; 02321 case(ZOOM_BOX_COLOR): 02322 string = g_strdup (_("Zoom box")); 02323 break; 02324 case(STROKE_COLOR): 02325 string = g_strdup (_("Stroke")); 02326 break; 02327 case(LOCK_COLOR): 02328 string = g_strdup (_("Lock")); 02329 break; 02330 case(OUTPUT_BACKGROUND_COLOR): 02331 string = g_strdup (_("Output background")); 02332 break; 02333 case(JUNCTION_COLOR): 02334 string = g_strdup (_("Net junction")); 02335 break; 02336 case(MESH_GRID_MAJOR_COLOR): 02337 string = g_strdup (_("Mesh grid major")); 02338 break; 02339 case(MESH_GRID_MINOR_COLOR): 02340 string = g_strdup (_("Mesh grid minor")); 02341 break; 02342 default: 02343 string = g_strdup (_("Unknown")); 02344 break; 02345 } 02346 return(string); 02347 } 02348 02360 static void 02361 color_menu_swatch_layout_data (GtkCellLayout *layout, 02362 GtkCellRenderer *cell, 02363 GtkTreeModel *model, 02364 GtkTreeIter *iter, 02365 gpointer data) 02366 { 02367 /* GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL *) data; */ 02368 GValue v = {0, }; 02369 gint idx; 02370 02371 /* Get the index of the color on this row */ 02372 gtk_tree_model_get_value (model, iter, 1, &v); 02373 idx = g_value_get_int (&v); 02374 02375 /* Set the cell's background color */ 02376 g_object_set (cell, "background-gdk", x_get_color (idx), NULL); 02377 } 02378 02387 static void 02388 color_menu_change_selection (GtkWidget *widget, 02389 gpointer data) 02390 { 02391 GSCHEM_TOPLEVEL *w_current = (GSCHEM_TOPLEVEL *) data; 02392 GtkComboBox *cbox = GTK_COMBO_BOX (widget); 02393 gint idx; 02394 GtkTreeIter iter; 02395 GValue v = {0, }; 02396 02397 if (!gtk_combo_box_get_active_iter (cbox, &iter)) { 02398 return; /* No color selected */ 02399 } 02400 gtk_tree_model_get_value (gtk_combo_box_get_model (cbox), 02401 &iter, 1, &v); 02402 idx = g_value_get_int (&v); 02403 02404 /* Stash the selected color in the GSCHEM_TOPLEVEL. 02405 * FIXME this is ugly. */ 02406 w_current->edit_color = idx; 02407 } 02408 02420 static GtkWidget * 02421 create_color_menu (GSCHEM_TOPLEVEL *w_current) 02422 { 02423 GtkListStore *store; 02424 GtkComboBox *cbox; 02425 GtkCellLayout *layout; 02426 GtkCellRenderer *text_cell; 02427 GtkCellRenderer *color_cell; 02428 02429 gint i; 02430 gchar *str; 02431 OBJECT *obj; 02432 GtkTreeIter iter; 02433 02434 obj = o_select_return_first_object (w_current); 02435 if (obj != NULL) 02436 w_current->edit_color = obj->color; 02437 02438 /* The columns are: name of color, index of color. */ 02439 store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT); 02440 cbox = GTK_COMBO_BOX (gtk_combo_box_new_with_model (GTK_TREE_MODEL (store))); 02441 layout = GTK_CELL_LAYOUT (cbox); /* For convenience */ 02442 02443 /* Renders the color swatch. Since this won't contain text, set a 02444 * minimum width. */ 02445 color_cell = GTK_CELL_RENDERER (gtk_cell_renderer_text_new()); 02446 g_object_set (color_cell, "width", 25, NULL); 02447 gtk_cell_layout_pack_start (layout, color_cell, FALSE); 02448 gtk_cell_layout_set_cell_data_func (layout, color_cell, 02449 color_menu_swatch_layout_data, 02450 (gpointer) w_current, 02451 NULL); 02452 02453 /* Renders the name of the color */ 02454 text_cell = GTK_CELL_RENDERER (gtk_cell_renderer_text_new()); 02455 g_object_set (text_cell, "xpad", 5, NULL); 02456 gtk_cell_layout_pack_start (layout, text_cell, TRUE); 02457 gtk_cell_layout_add_attribute (layout, text_cell, "text", 0); 02458 02459 /* Populate the list */ 02460 for (i = 0; i < MAX_COLORS; i++) { 02461 /* Skip 'invalid' colors. */ 02462 if (!x_color_display_enabled(i)) continue; 02463 02464 str = index2functionstring (i); 02465 gtk_list_store_append (store, &iter); 02466 gtk_list_store_set (store, &iter, 0, str, 1, i, -1); 02467 if (i == w_current->edit_color) 02468 gtk_combo_box_set_active_iter (cbox, &iter); 02469 } 02470 02471 g_signal_connect (cbox, 02472 "changed", 02473 GTK_SIGNAL_FUNC (color_menu_change_selection), 02474 w_current); 02475 02476 return GTK_WIDGET (cbox); 02477 } 02478 02483 void color_edit_dialog_apply(GtkWidget *w, GSCHEM_TOPLEVEL *w_current) 02484 { 02485 GList *s_current = NULL; 02486 OBJECT *object = NULL; 02487 02488 s_current = geda_list_get_glist( w_current->toplevel->page_current->selection_list ); 02489 02490 while(s_current != NULL) { 02491 02492 object = (OBJECT *) s_current->data; 02493 if (object == NULL) { 02494 fprintf(stderr, _("ERROR: NULL object in color_edit_dialog_apply!\n")); 02495 exit(-1); 02496 } 02497 02498 o_set_color (w_current->toplevel, object, w_current->edit_color); 02499 w_current->toplevel->page_current->CHANGED = 1; 02500 02501 s_current = g_list_next(s_current); 02502 } 02503 o_undo_savestate(w_current, UNDO_ALL); 02504 } 02505 02510 void color_edit_dialog_response(GtkWidget *widget, gint response, GSCHEM_TOPLEVEL *w_current) 02511 { 02512 switch (response) { 02513 case GTK_RESPONSE_REJECT: 02514 case GTK_RESPONSE_DELETE_EVENT: 02515 gtk_widget_destroy(w_current->clwindow); 02516 w_current->clwindow = NULL; 02517 break; 02518 case GTK_RESPONSE_ACCEPT: 02519 color_edit_dialog_apply(widget, w_current); 02520 break; 02521 default: 02522 printf("ERROR: color_edit_dialog_response(): strange signal %d\n",response); 02523 } 02524 } 02525 02526 02531 void color_edit_dialog (GSCHEM_TOPLEVEL *w_current) 02532 { 02533 GtkWidget *optionmenu; 02534 GtkWidget *label; 02535 GtkWidget *vbox; 02536 02537 if (!w_current->clwindow) { 02538 w_current->clwindow = gschem_dialog_new_with_buttons(_("Color Edit"), 02539 GTK_WINDOW(w_current->main_window), 02540 0, /* nonmodal dialog */ 02541 "color-edit", w_current, 02542 GTK_STOCK_CLOSE, 02543 GTK_RESPONSE_REJECT, 02544 GTK_STOCK_APPLY, 02545 GTK_RESPONSE_ACCEPT, 02546 NULL); 02547 02548 /* Set the alternative button order (ok, cancel, help) for other systems */ 02549 gtk_dialog_set_alternative_button_order(GTK_DIALOG(w_current->clwindow), 02550 GTK_RESPONSE_ACCEPT, 02551 GTK_RESPONSE_REJECT, 02552 -1); 02553 02554 gtk_window_position (GTK_WINDOW (w_current->clwindow), 02555 GTK_WIN_POS_MOUSE); 02556 02557 gtk_dialog_set_default_response (GTK_DIALOG (w_current->clwindow), 02558 GTK_RESPONSE_ACCEPT); 02559 02560 g_signal_connect (G_OBJECT (w_current->clwindow), "response", 02561 G_CALLBACK (color_edit_dialog_response), 02562 w_current); 02563 02564 gtk_container_border_width(GTK_CONTAINER(w_current->clwindow), 02565 DIALOG_BORDER_SPACING); 02566 vbox = GTK_DIALOG(w_current->clwindow)->vbox; 02567 gtk_box_set_spacing(GTK_BOX(vbox), DIALOG_V_SPACING); 02568 02569 label = gtk_label_new(_("Object color:")); 02570 gtk_misc_set_alignment(GTK_MISC(label),0,0); 02571 gtk_box_pack_start(GTK_BOX(vbox), label, FALSE, FALSE, 0); 02572 02573 optionmenu = create_color_menu (w_current); 02574 gtk_box_pack_start(GTK_BOX(vbox), 02575 optionmenu, FALSE, FALSE, 0); 02576 gtk_widget_show_all(w_current->clwindow); 02577 } 02578 02579 else { /* dialog already created */ 02580 gtk_window_present(GTK_WINDOW(w_current->clwindow)); 02581 } 02582 } 02583 02584 /***************** End of color edit dialog box *********************/ 02585 02586 /***************** Start of help/keymapping dialog box **************/ 02587 02592 void x_dialog_hotkeys_response(GtkWidget *w, gint response, 02593 GSCHEM_TOPLEVEL *w_current) 02594 { 02595 switch(response) { 02596 case GTK_RESPONSE_REJECT: 02597 case GTK_RESPONSE_DELETE_EVENT: 02598 /* void */ 02599 break; 02600 default: 02601 printf("x_dialog_hotkeys_response(): strange signal %d\n", response); 02602 } 02603 /* clean up */ 02604 gtk_widget_destroy(w_current->hkwindow); 02605 w_current->hkwindow = NULL; 02606 } 02607 02613 void x_dialog_hotkeys (GSCHEM_TOPLEVEL *w_current) 02614 { 02615 GtkWidget *vbox, *scrolled_win; 02616 GtkListStore *store; 02617 GtkWidget *treeview; 02618 GtkCellRenderer *renderer; 02619 GtkTreeViewColumn *column; 02620 02621 if (!w_current->hkwindow) { 02622 w_current->hkwindow = gschem_dialog_new_with_buttons(_("Hotkeys"), 02623 GTK_WINDOW(w_current->main_window), 02624 0, /* not modal */ 02625 "hotkeys", w_current, 02626 GTK_STOCK_CLOSE, 02627 GTK_RESPONSE_REJECT, 02628 NULL); 02629 02630 gtk_window_position (GTK_WINDOW (w_current->hkwindow), 02631 GTK_WIN_POS_NONE); 02632 02633 g_signal_connect (G_OBJECT (w_current->hkwindow), "response", 02634 G_CALLBACK (x_dialog_hotkeys_response), 02635 w_current); 02636 02637 gtk_dialog_set_default_response(GTK_DIALOG(w_current->hkwindow), 02638 GTK_RESPONSE_ACCEPT); 02639 02640 gtk_container_border_width (GTK_CONTAINER (w_current->hkwindow), 02641 DIALOG_BORDER_SPACING); 02642 gtk_widget_set_usize(w_current->hkwindow, 300,300); 02643 02644 vbox = GTK_DIALOG(w_current->hkwindow)->vbox; 02645 gtk_box_set_spacing(GTK_BOX(vbox), DIALOG_V_SPACING); 02646 02647 scrolled_win = gtk_scrolled_window_new (NULL, NULL); 02648 gtk_box_pack_start (GTK_BOX (vbox), scrolled_win, TRUE, TRUE, 0); 02649 gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scrolled_win), 02650 GTK_POLICY_AUTOMATIC, 02651 GTK_POLICY_AUTOMATIC); 02652 02653 /* the model */ 02654 store = g_keys_to_list_store (); 02655 02656 /* the tree view */ 02657 treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store)); 02658 gtk_container_add(GTK_CONTAINER(scrolled_win), treeview); 02659 02660 /* the columns */ 02661 renderer = gtk_cell_renderer_text_new (); 02662 column = gtk_tree_view_column_new_with_attributes (_("Function"), 02663 renderer, 02664 "text", 02665 0, 02666 NULL); 02667 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); 02668 renderer = gtk_cell_renderer_text_new (); 02669 column = gtk_tree_view_column_new_with_attributes (_("Keystroke(s)"), 02670 renderer, 02671 "text", 02672 1, 02673 NULL); 02674 gtk_tree_view_append_column (GTK_TREE_VIEW(treeview), column); 02675 02676 /* show all recursively */ 02677 gtk_widget_show_all(w_current->hkwindow); 02678 } 02679 02680 else { /* dialog already created */ 02681 gtk_window_present(GTK_WINDOW(w_current->hkwindow)); 02682 } 02683 } 02684 02685 /***************** End of help/keymapping dialog box ****************/ 02686 02687 /*********** Start of misc support functions for dialog boxes *******/ 02688 extern GtkWidget *stwindow; 02689 02695 void x_dialog_raise_all(GSCHEM_TOPLEVEL *w_current) 02696 { 02697 if(w_current->sowindow) { 02698 gdk_window_raise(w_current->sowindow->window); 02699 } 02700 if(w_current->cswindow) { 02701 gdk_window_raise(w_current->cswindow->window); 02702 } 02703 if(w_current->iwindow) { 02704 gdk_window_raise(w_current->iwindow->window); 02705 } 02706 if(w_current->tiwindow) { 02707 gdk_window_raise(w_current->tiwindow->window); 02708 } 02709 if(w_current->tewindow) { 02710 gdk_window_raise(w_current->tewindow->window); 02711 } 02712 if(w_current->sewindow) { 02713 gdk_window_raise(w_current->sewindow->window); 02714 } 02715 if(w_current->aawindow) { 02716 gdk_window_raise(w_current->aawindow->window); 02717 } 02718 if(w_current->mawindow) { 02719 gdk_window_raise(w_current->mawindow->window); 02720 } 02721 if(w_current->aewindow) { 02722 gdk_window_raise(w_current->aewindow->window); 02723 } 02724 if(w_current->trwindow) { 02725 gdk_window_raise(w_current->trwindow->window); 02726 } 02727 if(w_current->tswindow) { 02728 gdk_window_raise(w_current->tswindow->window); 02729 } 02730 if(w_current->hkwindow) { 02731 gdk_window_raise(w_current->hkwindow->window); 02732 } 02733 if(w_current->cowindow) { 02734 gdk_window_raise(w_current->cowindow->window); 02735 } 02736 if(w_current->clwindow) { 02737 gdk_window_raise(w_current->clwindow->window); 02738 } 02739 02740 } 02741 02742 /*********** End of misc support functions for dialog boxes *******/ 02743 02744 /***************** Start of generic message dialog box *******************/ 02745 02751 void generic_msg_dialog (const char *msg) 02752 { 02753 GtkWidget *dialog; 02754 02755 dialog = gtk_message_dialog_new (NULL, 02756 GTK_DIALOG_MODAL | 02757 GTK_DIALOG_DESTROY_WITH_PARENT, 02758 GTK_MESSAGE_INFO, 02759 GTK_BUTTONS_OK, 02760 "%s", msg); 02761 02762 gtk_dialog_run (GTK_DIALOG (dialog)); 02763 gtk_widget_destroy (dialog); 02764 02765 } 02766 02767 /***************** End of generic message dialog box *********************/ 02768 02769 /***************** Start of generic confirm dialog box *******************/ 02770 02776 int generic_confirm_dialog (const char *msg) 02777 { 02778 GtkWidget *dialog; 02779 gint r; 02780 02781 dialog = gtk_message_dialog_new (NULL, 02782 GTK_DIALOG_MODAL | 02783 GTK_DIALOG_DESTROY_WITH_PARENT, 02784 GTK_MESSAGE_INFO, 02785 GTK_BUTTONS_OK_CANCEL, 02786 "%s", msg); 02787 02788 r = gtk_dialog_run (GTK_DIALOG (dialog)); 02789 gtk_widget_destroy (dialog); 02790 02791 if (r == GTK_RESPONSE_OK) 02792 return 1; 02793 else 02794 return 0; 02795 } 02796 02797 /***************** End of generic confirm dialog box *********************/ 02798 02799 /***************** Start of generic file select dialog box ***************/ 02807 char *generic_filesel_dialog (const char *msg, const char *templ, gint flags) 02808 { 02809 GtkWidget *dialog; 02810 gchar *result = NULL, *folder, *seed; 02811 char *title; 02812 static gchar *path = NULL; 02813 static gchar *shortcuts = NULL; 02814 02815 /* Default to load if not specified. Maybe this should cause an error. */ 02816 if (! (flags & (FSB_LOAD | FSB_SAVE))) { 02817 flags = flags | FSB_LOAD; 02818 } 02819 02820 if (flags & FSB_LOAD) { 02821 title = g_strdup_printf("%s: Open", msg); 02822 dialog = gtk_file_chooser_dialog_new (title, 02823 NULL, 02824 GTK_FILE_CHOOSER_ACTION_OPEN, 02825 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, 02826 GTK_STOCK_OPEN, GTK_RESPONSE_OK, 02827 NULL); 02828 /* Since this is a load dialog box, the file must exist! */ 02829 flags = flags | FSB_MUST_EXIST; 02830 02831 } else { 02832 title = g_strdup_printf("%s: Save", msg); 02833 dialog = gtk_file_chooser_dialog_new (title, 02834 NULL, 02835 GTK_FILE_CHOOSER_ACTION_SAVE, 02836 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, 02837 GTK_STOCK_OPEN, GTK_RESPONSE_OK, 02838 NULL); 02839 } 02840 02841 /* Set the alternative button order (ok, cancel, help) for other systems */ 02842 gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), 02843 GTK_RESPONSE_OK, 02844 GTK_RESPONSE_CANCEL, 02845 -1); 02846 02847 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); 02848 02849 /* Pick the current default folder to look for files in */ 02850 if (path && *path) { 02851 gtk_file_chooser_set_current_folder (GTK_FILE_CHOOSER (dialog), path); 02852 } 02853 02854 02855 /* Pick the current template (*.rc) or default file name */ 02856 if (templ && *templ) { 02857 if (flags & FSB_SAVE) { 02858 gtk_file_chooser_set_current_name (GTK_FILE_CHOOSER (dialog), templ); 02859 } else { 02860 gtk_file_chooser_select_filename (GTK_FILE_CHOOSER (dialog), templ); 02861 } 02862 } 02863 02864 02865 if (shortcuts && *shortcuts) { 02866 printf ("shortcuts = \"%s\"\n", shortcuts); 02867 folder = g_strdup (shortcuts); 02868 seed = folder; 02869 while ((folder = strtok (seed, ":")) != NULL) { 02870 gtk_file_chooser_add_shortcut_folder (GTK_FILE_CHOOSER (dialog), 02871 folder, NULL); 02872 seed = NULL; 02873 } 02874 02875 g_free (folder); 02876 } 02877 02878 if (gtk_dialog_run (GTK_DIALOG (dialog)) == GTK_RESPONSE_OK) { 02879 result = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dialog)); 02880 folder = gtk_file_chooser_get_current_folder (GTK_FILE_CHOOSER (dialog)); 02887 } 02888 gtk_widget_destroy (dialog); 02889 02890 g_free (title); 02891 02892 return result; 02893 02894 } 02895 02896 /***************** End of generic file select dialog box *****************/ 02897 02898 /*********** Start of find text dialog box *******/ 02899 02900 int start_find; 02901 PAGE *remember_page; 02902 02908 void find_text_dialog_response(GtkWidget *w, gint response, 02909 GSCHEM_TOPLEVEL *w_current) 02910 { 02911 TOPLEVEL *toplevel = w_current->toplevel; 02912 GtkWidget *textentry; 02913 GtkWidget *checkdescend; 02914 gchar *string; 02915 gint done=0, close=0; 02916 02917 switch (response) { 02918 case GTK_RESPONSE_ACCEPT: 02919 textentry = g_object_get_data(G_OBJECT(w_current->tfindwindow),"textentry"); 02920 string = (gchar*) gtk_entry_get_text(GTK_ENTRY(textentry)); 02921 checkdescend = g_object_get_data(G_OBJECT(w_current->tfindwindow),"checkdescend"); 02922 02923 strncpy(generic_textstring, string, sizeof(generic_textstring)-1); 02924 generic_textstring[sizeof(generic_textstring)-1] = '\0'; 02925 02926 if (remember_page != toplevel->page_current) { 02927 s_page_goto(toplevel, remember_page); 02928 } 02929 done = 02930 o_edit_find_text (w_current, s_page_objects (remember_page), string, 02931 gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON 02932 (checkdescend)), 02933 !start_find); 02934 if (done) { 02935 o_invalidate_all (w_current); 02936 close = 1; 02937 } 02938 start_find = 0; 02939 break; 02940 case GTK_RESPONSE_REJECT: 02941 case GTK_RESPONSE_DELETE_EVENT: 02942 close = 1; 02943 break; 02944 default: 02945 printf("find_text_dialog_response(): strange signal %d\n", response); 02946 } 02947 if (close) { 02948 gtk_widget_destroy(w_current->tfindwindow); 02949 w_current->tfindwindow = NULL; 02950 } 02951 } 02952 02957 void find_text_dialog(GSCHEM_TOPLEVEL *w_current) 02958 { 02959 GtkWidget *label = NULL; 02960 GtkWidget *vbox; 02961 GtkWidget *checkdescend; 02962 GtkWidget *textentry; 02963 OBJECT *object = NULL; 02964 02965 start_find = 1; 02966 remember_page = w_current->toplevel->page_current; 02967 if ((object = o_select_return_first_object(w_current)) != NULL) { 02968 if (object->type == OBJ_TEXT) { 02969 strncpy (generic_textstring, 02970 o_text_get_string (w_current->toplevel, object), 02971 sizeof(generic_textstring)-1); 02972 generic_textstring[sizeof(generic_textstring)-1] = '\0'; 02973 } 02974 } 02975 02976 if (!w_current->tfindwindow) { 02977 w_current->tfindwindow = gschem_dialog_new_with_buttons(_("Find Text"), 02978 GTK_WINDOW(w_current->main_window), 02979 0, /* not modal GTK_DIALOG_MODAL */ 02980 "find-text", w_current, 02981 GTK_STOCK_CLOSE, 02982 GTK_RESPONSE_REJECT, 02983 GTK_STOCK_FIND, 02984 GTK_RESPONSE_ACCEPT, 02985 NULL); 02986 02987 /* Set the alternative button order (ok, cancel, help) for other systems */ 02988 gtk_dialog_set_alternative_button_order(GTK_DIALOG(w_current->tfindwindow), 02989 GTK_RESPONSE_ACCEPT, 02990 GTK_RESPONSE_REJECT, 02991 -1); 02992 02993 gtk_window_position(GTK_WINDOW(w_current->tfindwindow), 02994 GTK_WIN_POS_MOUSE); 02995 02996 g_signal_connect (G_OBJECT (w_current->tfindwindow), "response", 02997 G_CALLBACK (find_text_dialog_response), 02998 w_current); 02999 03000 gtk_dialog_set_default_response(GTK_DIALOG(w_current->tfindwindow), 03001 GTK_RESPONSE_ACCEPT); 03002 03003 gtk_container_border_width(GTK_CONTAINER(w_current->tfindwindow), 03004 DIALOG_BORDER_SPACING); 03005 vbox = GTK_DIALOG(w_current->tfindwindow)->vbox; 03006 gtk_box_set_spacing(GTK_BOX(vbox), DIALOG_V_SPACING); 03007 03008 label = gtk_label_new(_("Text to find:")); 03009 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 03010 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); 03011 03012 textentry = gtk_entry_new_with_max_length(20); 03013 gtk_editable_select_region(GTK_EDITABLE(textentry), 0, -1); 03014 gtk_box_pack_start(GTK_BOX(vbox), textentry, FALSE, FALSE, 0); 03015 gtk_entry_set_activates_default(GTK_ENTRY(textentry), TRUE); 03016 gtk_widget_grab_focus(textentry); 03017 03018 checkdescend = gtk_check_button_new_with_label(_("descend into hierarchy")); 03019 gtk_box_pack_start(GTK_BOX(vbox), checkdescend, TRUE, TRUE, 0); 03020 03021 GLADE_HOOKUP_OBJECT(w_current->tfindwindow, textentry, "textentry"); 03022 GLADE_HOOKUP_OBJECT(w_current->tfindwindow, checkdescend, "checkdescend"); 03023 03024 gtk_widget_show_all(w_current->tfindwindow); 03025 } 03026 03027 else { /* dialog already created */ 03028 gtk_window_present(GTK_WINDOW(w_current->tfindwindow)); 03029 } 03030 03031 /* always select the text string in the entry */ 03032 textentry = g_object_get_data (G_OBJECT (w_current->tfindwindow), "textentry"); 03033 gtk_entry_set_text(GTK_ENTRY(textentry), generic_textstring); 03034 gtk_entry_select_region(GTK_ENTRY(textentry), 0, -1); 03035 } 03036 03037 /*********** End of find text dialog box *******/ 03038 03039 /*********** Start of hide text dialog box *******/ 03040 03046 void hide_text_dialog_response(GtkWidget *w, gint response, 03047 GSCHEM_TOPLEVEL *w_current) 03048 { 03049 GtkWidget *textentry; 03050 gchar *string; 03051 03052 switch (response) { 03053 case GTK_RESPONSE_ACCEPT: 03054 textentry = g_object_get_data(G_OBJECT(w_current->thidewindow),"textentry"); 03055 string = (gchar*) gtk_entry_get_text(GTK_ENTRY(textentry)); 03056 03057 strncpy(generic_textstring, string, sizeof(generic_textstring)-1); 03058 generic_textstring[sizeof(generic_textstring)-1] = '\0'; 03059 o_edit_hide_specific_text (w_current, 03060 s_page_objects (w_current->toplevel->page_current), 03061 string); 03062 break; 03063 case GTK_RESPONSE_REJECT: 03064 case GTK_RESPONSE_DELETE_EVENT: 03065 gtk_widget_destroy(w_current->thidewindow); 03066 w_current->thidewindow = NULL; 03067 break; 03068 default: 03069 printf("show_text_dialog_response(): strange signal %d\n",response); 03070 } 03071 } 03072 03077 void hide_text_dialog(GSCHEM_TOPLEVEL * w_current) 03078 { 03079 GtkWidget *label = NULL; 03080 GtkWidget *textentry; 03081 GtkWidget *vbox; 03082 03083 if (!w_current->thidewindow) { 03084 w_current->thidewindow = gschem_dialog_new_with_buttons(_("Hide Text"), 03085 GTK_WINDOW(w_current->main_window), 03086 0, /* not modal GTK_DIALOG_MODAL, */ 03087 "hide-text", w_current, 03088 GTK_STOCK_CLOSE, 03089 GTK_RESPONSE_REJECT, 03090 GTK_STOCK_APPLY, 03091 GTK_RESPONSE_ACCEPT, 03092 NULL); 03093 03094 /* Set the alternative button order (ok, cancel, help) for other systems */ 03095 gtk_dialog_set_alternative_button_order(GTK_DIALOG(w_current->thidewindow), 03096 GTK_RESPONSE_ACCEPT, 03097 GTK_RESPONSE_REJECT, 03098 -1); 03099 03100 gtk_window_position(GTK_WINDOW(w_current->thidewindow), 03101 GTK_WIN_POS_MOUSE); 03102 03103 g_signal_connect (G_OBJECT (w_current->thidewindow), "response", 03104 G_CALLBACK (hide_text_dialog_response), 03105 w_current); 03106 03107 gtk_dialog_set_default_response(GTK_DIALOG(w_current->thidewindow), 03108 GTK_RESPONSE_ACCEPT); 03109 03110 gtk_container_border_width(GTK_CONTAINER(w_current->thidewindow), 03111 DIALOG_BORDER_SPACING); 03112 vbox = GTK_DIALOG(w_current->thidewindow)->vbox; 03113 gtk_box_set_spacing(GTK_BOX(vbox), DIALOG_V_SPACING); 03114 03115 label = gtk_label_new(_("Hide text starting with:")); 03116 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 03117 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); 03118 03119 textentry = gtk_entry_new_with_max_length(20); 03120 gtk_box_pack_start(GTK_BOX(vbox), textentry, FALSE, FALSE, 0); 03121 gtk_entry_set_activates_default(GTK_ENTRY(textentry), TRUE); 03122 gtk_widget_grab_focus(textentry); 03123 03124 GLADE_HOOKUP_OBJECT(w_current->thidewindow, textentry, "textentry"); 03125 gtk_widget_show_all(w_current->thidewindow); 03126 } 03127 03128 else { /* dialog already created, just select it */ 03129 gtk_window_present(GTK_WINDOW(w_current->thidewindow)); 03130 } 03131 03132 /* always select the text in the search entry */ 03133 textentry = g_object_get_data (G_OBJECT (w_current->thidewindow), "textentry"); 03134 gtk_entry_set_text(GTK_ENTRY(textentry), generic_textstring); 03135 gtk_entry_select_region(GTK_ENTRY(textentry), 0, -1); 03136 } 03137 03138 /*********** End of hide text dialog box *******/ 03139 03140 /*********** Start of show text dialog box *******/ 03141 03147 void show_text_dialog_response(GtkWidget *widget, gint response, 03148 GSCHEM_TOPLEVEL *w_current) 03149 { 03150 GtkWidget *textentry; 03151 gchar *string; 03152 03153 switch (response) { 03154 case GTK_RESPONSE_ACCEPT: 03155 textentry = g_object_get_data(G_OBJECT(w_current->tshowwindow),"textentry"); 03156 string = (gchar*) gtk_entry_get_text(GTK_ENTRY(textentry)); 03157 03158 strncpy(generic_textstring, string, sizeof(generic_textstring)-1); 03159 generic_textstring[sizeof(generic_textstring)-1] = '\0'; 03160 o_edit_show_specific_text (w_current, 03161 s_page_objects (w_current->toplevel->page_current), 03162 string); 03163 break; 03164 case GTK_RESPONSE_REJECT: 03165 case GTK_RESPONSE_DELETE_EVENT: 03166 gtk_widget_destroy(w_current->tshowwindow); 03167 w_current->tshowwindow = NULL; 03168 break; 03169 default: 03170 printf("show_text_dialog_response(): strange signal %d\n",response); 03171 } 03172 } 03173 03178 void show_text_dialog(GSCHEM_TOPLEVEL * w_current) 03179 { 03180 GtkWidget *label = NULL; 03181 GtkWidget *textentry; 03182 GtkWidget *vbox; 03183 03184 if (!w_current->tshowwindow) { 03185 w_current->tshowwindow = gschem_dialog_new_with_buttons(_("Show Text"), 03186 GTK_WINDOW(w_current->main_window), 03187 0, /* not modal GTK_DIALOG_MODAL, */ 03188 "show-text", w_current, 03189 GTK_STOCK_CLOSE, 03190 GTK_RESPONSE_REJECT, 03191 GTK_STOCK_APPLY, 03192 GTK_RESPONSE_ACCEPT, 03193 NULL); 03194 03195 /* Set the alternative button order (ok, cancel, help) for other systems */ 03196 gtk_dialog_set_alternative_button_order(GTK_DIALOG(w_current->tshowwindow), 03197 GTK_RESPONSE_ACCEPT, 03198 GTK_RESPONSE_REJECT, 03199 -1); 03200 03201 gtk_window_position(GTK_WINDOW(w_current->tshowwindow), 03202 GTK_WIN_POS_MOUSE); 03203 03204 g_signal_connect (G_OBJECT (w_current->tshowwindow), "response", 03205 G_CALLBACK (show_text_dialog_response), 03206 w_current); 03207 03208 gtk_dialog_set_default_response(GTK_DIALOG(w_current->tshowwindow), 03209 GTK_RESPONSE_ACCEPT); 03210 03211 gtk_container_border_width(GTK_CONTAINER(w_current->tshowwindow), 03212 DIALOG_BORDER_SPACING); 03213 vbox = GTK_DIALOG(w_current->tshowwindow)->vbox; 03214 gtk_box_set_spacing(GTK_BOX(vbox), DIALOG_V_SPACING); 03215 03216 label = gtk_label_new(_("Show text starting with:")); 03217 gtk_misc_set_alignment(GTK_MISC(label), 0, 0); 03218 gtk_box_pack_start(GTK_BOX(vbox), label, TRUE, TRUE, 0); 03219 03220 textentry = gtk_entry_new_with_max_length(20); 03221 gtk_box_pack_start(GTK_BOX(vbox), textentry, FALSE, FALSE, 0); 03222 gtk_entry_set_activates_default(GTK_ENTRY(textentry), TRUE); 03223 gtk_widget_grab_focus(textentry); 03224 03225 GLADE_HOOKUP_OBJECT(w_current->tshowwindow, textentry, "textentry"); 03226 gtk_widget_show_all(w_current->tshowwindow); 03227 } 03228 03229 else { /* dialog already created. Show it */ 03230 gtk_window_present(GTK_WINDOW(w_current->tshowwindow)); 03231 } 03232 03233 /* always select the text in the entry */ 03234 textentry = g_object_get_data (G_OBJECT (w_current->tshowwindow), "textentry"); 03235 gtk_entry_set_text(GTK_ENTRY(textentry), generic_textstring); 03236 gtk_entry_select_region(GTK_ENTRY(textentry), 0, -1); 03237 } 03238 03239 /*********** End of show text dialog box *******/ 03240 03241 /*********** Start of some Gtk utils *******/ 03242 03247 void select_all_text_in_textview(GtkTextView *textview) 03248 { 03249 GtkTextBuffer *textbuffer; 03250 GtkTextIter start, end; 03251 03252 textbuffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(textview)); 03253 gtk_text_buffer_get_bounds (textbuffer, &start, &end); 03254 gtk_text_buffer_select_range(textbuffer, &start, &end); 03255 } 03256 03262 int text_view_calculate_real_tab_width(GtkTextView *textview, int tab_size) 03263 { 03264 PangoLayout *layout; 03265 gchar *tab_string; 03266 gint tab_width = 0; 03267 03268 if (tab_size == 0) 03269 return -1; 03270 03271 tab_string = g_strnfill (tab_size, ' '); 03272 03273 layout = gtk_widget_create_pango_layout ( 03274 GTK_WIDGET (textview), 03275 tab_string); 03276 g_free (tab_string); 03277 03278 if (layout != NULL) { 03279 pango_layout_get_pixel_size (layout, &tab_width, NULL); 03280 g_object_unref (G_OBJECT (layout)); 03281 } else 03282 tab_width = -1; 03283 03284 return tab_width; 03285 03286 } 03287 03288 /*********** End of some Gtk utils *******/ 03289 03290 /*********** Start of major symbol changed dialog box *******/ 03291 03297 void major_changed_dialog(GSCHEM_TOPLEVEL* w_current) 03298 { 03299 GtkWidget* dialog; 03300 char* refdes_string = NULL; 03301 char* tmp; 03302 03303 if (w_current->toplevel->major_changed_refdes) { 03304 03305 GList* current = w_current->toplevel->major_changed_refdes; 03306 while (current) 03307 { 03308 char *value = (char*) current->data; 03309 03310 if (!refdes_string) 03311 { 03312 refdes_string = g_strdup (value); 03313 } else { 03314 tmp = g_strconcat (refdes_string, "\n", value, NULL); 03315 g_free(refdes_string); 03316 refdes_string = tmp; 03317 } 03318 03319 current = g_list_next(current); 03320 } 03321 03322 tmp = g_strconcat (refdes_string, 03323 "\n\nBe sure to verify each of these symbols!", 03324 NULL); 03325 g_free(refdes_string); 03326 refdes_string = tmp; 03327 03328 dialog = gtk_message_dialog_new ((GtkWindow*) w_current->main_window, 03329 GTK_DIALOG_DESTROY_WITH_PARENT, 03330 GTK_MESSAGE_ERROR, 03331 GTK_BUTTONS_CLOSE, 03332 "Major symbol changes detected in refdes:\n\n%s\n", 03333 refdes_string); 03334 03335 gtk_widget_show(dialog); 03336 03337 g_signal_connect_swapped (dialog, "response", 03338 G_CALLBACK (gtk_widget_destroy), 03339 dialog); 03340 03341 g_free(refdes_string); 03342 } 03343 } 03344 03345 /*********** End of major symbol changed dialog box *******/ 03346 03347 /***************** Start of Close Confirmation dialog box ************/ 03348 03349 #define TYPE_CLOSE_CONFIRMATION_DIALOG (close_confirmation_dialog_get_type ()) 03350 #define CLOSE_CONFIRMATION_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), TYPE_CLOSE_CONFIRMATION_DIALOG, CloseConfirmationDialog)) 03351 #define CLOSE_CONFIRMATION_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), TYPE_CLOSE_CONFIRMATION_DIALOG, CloseConfirmationDialogClass)) 03352 #define IS_CLOSE_CONFIRMATION_DIALOG(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TYPE_CLOSE_CONFIRMATION_DIALOG)) 03353 #define IS_CLOSE_CONFIRMATION_DIALOG_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), TYPE_CLOSE_CONFIRMATION_DIALOG)) 03354 #define CLOSE_CONFIRMATION_DIALOG_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj),TYPE_CLOSE_CONFIRMATION_DIALOG, CloseConfirmationDialogClass)) 03355 03356 03357 typedef struct _CloseConfirmationDialog CloseConfirmationDialog; 03358 typedef struct _CloseConfirmationDialogClass CloseConfirmationDialogClass; 03359 03360 struct _CloseConfirmationDialog 03361 { 03362 GtkDialog parent; 03363 03364 GtkListStore *store_unsaved_pages; 03365 }; 03366 03367 struct _CloseConfirmationDialogClass 03368 { 03369 GtkDialogClass parent_class; 03370 }; 03371 03372 03373 enum { 03374 PROP_UNSAVED_PAGE=1, 03375 PROP_UNSAVED_PAGES, 03376 PROP_SELECTED_PAGES 03377 }; 03378 03379 enum { 03380 COLUMN_SAVE, 03381 COLUMN_PAGE, 03382 NUM_COLUMNS 03383 }; 03384 03385 03386 static gpointer close_confirmation_dialog_parent_class = NULL; 03387 03388 03389 static void close_confirmation_dialog_class_init (CloseConfirmationDialogClass *klass); 03390 static void close_confirmation_dialog_init (CloseConfirmationDialog *self); 03391 static void close_confirmation_dialog_set_property (GObject *object, 03392 guint property_id, 03393 const GValue *value, 03394 GParamSpec *pspec); 03395 static void close_confirmation_dialog_get_property (GObject *object, 03396 guint property_id, 03397 GValue *value, 03398 GParamSpec *pspec); 03399 static GObject* close_confirmation_dialog_constructor (GType type, 03400 guint n_construct_properties, 03401 GObjectConstructParam *construct_params); 03402 03403 GList *close_confirmation_dialog_get_selected_pages (CloseConfirmationDialog *dialog); 03404 03405 03406 03407 GType 03408 close_confirmation_dialog_get_type () 03409 { 03410 static GType close_confirmation_dialog_type = 0; 03411 03412 if (!close_confirmation_dialog_type) { 03413 static const GTypeInfo close_confirmation_dialog_info = { 03414 sizeof(CloseConfirmationDialogClass), 03415 NULL, /* base_init */ 03416 NULL, /* base_finalize */ 03417 (GClassInitFunc) close_confirmation_dialog_class_init, 03418 NULL, /* class_finalize */ 03419 NULL, /* class_data */ 03420 sizeof(CloseConfirmationDialog), 03421 0, /* n_preallocs */ 03422 (GInstanceInitFunc) close_confirmation_dialog_init, 03423 }; 03424 03425 close_confirmation_dialog_type = 03426 g_type_register_static (GTK_TYPE_DIALOG, 03427 "CloseConfirmationDialog", 03428 &close_confirmation_dialog_info, 0); 03429 } 03430 03431 return close_confirmation_dialog_type; 03432 } 03433 03434 static void 03435 close_confirmation_dialog_class_init (CloseConfirmationDialogClass *klass) 03436 { 03437 GObjectClass *gobject_class = G_OBJECT_CLASS (klass); 03438 03439 close_confirmation_dialog_parent_class = g_type_class_peek_parent (klass); 03440 03441 gobject_class->constructor = close_confirmation_dialog_constructor; 03442 gobject_class->set_property = close_confirmation_dialog_set_property; 03443 gobject_class->get_property = close_confirmation_dialog_get_property; 03444 03445 g_object_class_install_property ( 03446 gobject_class, PROP_UNSAVED_PAGE, 03447 g_param_spec_pointer ("unsaved-page", 03448 "", 03449 "", 03450 G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE)); 03451 g_object_class_install_property ( 03452 gobject_class, PROP_UNSAVED_PAGES, 03453 g_param_spec_pointer ("unsaved-pages", 03454 "", 03455 "", 03456 G_PARAM_CONSTRUCT_ONLY | G_PARAM_WRITABLE)); 03457 g_object_class_install_property ( 03458 gobject_class, PROP_SELECTED_PAGES, 03459 g_param_spec_pointer ("selected-pages", 03460 "", 03461 "", 03462 G_PARAM_READABLE)); 03463 03464 } 03465 03466 static void 03467 close_confirmation_dialog_init (CloseConfirmationDialog *self) 03468 { 03469 /* create model for treeview and populate */ 03470 self->store_unsaved_pages = gtk_list_store_new (NUM_COLUMNS, 03471 G_TYPE_BOOLEAN, /* save? */ 03472 G_TYPE_POINTER); /* page */ 03473 03474 } 03475 03484 static gint 03485 count_pages (GtkTreeModel *model) 03486 { 03487 GtkTreeIter iter; 03488 gint n_pages; 03489 03490 gtk_tree_model_get_iter_first (model, &iter); 03491 for (n_pages = 1; 03492 gtk_tree_model_iter_next (model, &iter); 03493 n_pages++); 03494 03495 return n_pages; 03496 } 03497 03513 static gchar* 03514 get_page_name (GtkTreeModel *model, GtkTreeIter *piter) 03515 { 03516 GtkTreeIter iter; 03517 PAGE *page; 03518 03519 g_return_val_if_fail (GTK_IS_TREE_MODEL (model), NULL); 03520 03521 if (piter == NULL) { 03522 gtk_tree_model_get_iter_first (model, &iter); 03523 } else { 03524 iter = *piter; 03525 } 03526 03527 gtk_tree_model_get (model, &iter, 03528 COLUMN_PAGE, &page, 03529 -1); 03530 g_assert (page != NULL && page->page_filename != NULL); 03531 return g_path_get_basename (page->page_filename); 03532 } 03533 03546 static void 03547 close_confirmation_dialog_set_page_name (GtkTreeViewColumn *tree_column, 03548 GtkCellRenderer *cell, 03549 GtkTreeModel *tree_model, 03550 GtkTreeIter *iter, 03551 gpointer data) 03552 { 03553 gchar *page_name; 03554 03555 page_name = get_page_name (tree_model, iter); 03556 g_object_set (cell, 03557 "text", page_name, 03558 NULL); 03559 g_free (page_name); 03560 03561 } 03562 03573 static void 03574 close_confirmation_dialog_callback_renderer_toggled (GtkCellRendererToggle *cell_renderer, 03575 gchar *path, 03576 gpointer user_data) 03577 { 03578 CloseConfirmationDialog *dialog = CLOSE_CONFIRMATION_DIALOG (user_data); 03579 GtkTreeModel *model; 03580 GtkTreeIter iter; 03581 gboolean save; 03582 03583 model = GTK_TREE_MODEL (dialog->store_unsaved_pages); 03584 03585 if (!gtk_tree_model_get_iter_from_string (model, &iter, path)) { 03586 return; 03587 } 03588 gtk_tree_model_get (model, &iter, 03589 COLUMN_SAVE, &save, 03590 -1); 03591 gtk_list_store_set (GTK_LIST_STORE (model), &iter, 03592 COLUMN_SAVE, (save != TRUE), 03593 -1); 03594 03595 } 03596 03607 static GtkWidget* 03608 close_confirmation_dialog_build_page_list (CloseConfirmationDialog *dialog) 03609 { 03610 GtkWidget *vbox, *scrolled_window, *treeview, *label; 03611 GtkCellRenderer *renderer; 03612 GtkTreeViewColumn *column; 03613 const gchar *text; 03614 03615 /* place the treeview and its caption into their own box */ 03616 vbox = GTK_WIDGET (g_object_new (GTK_TYPE_VBOX, 03617 /* GtkBox */ 03618 "homogeneous", FALSE, 03619 "spacing", 8, 03620 NULL)); 03621 03622 /* the list of pages with changes */ 03623 /* - scrolled window as container for the treeview first */ 03624 scrolled_window = GTK_WIDGET (g_object_new (GTK_TYPE_SCROLLED_WINDOW, 03625 /* GtkScrolledWindow */ 03626 "hscrollbar-policy", GTK_POLICY_AUTOMATIC, 03627 "vscrollbar-policy", GTK_POLICY_AUTOMATIC, 03628 "shadow-type", GTK_SHADOW_IN, 03629 NULL)); 03630 /* - then the treeview */ 03631 /* create model for treeview and populate */ 03632 treeview = GTK_WIDGET (g_object_new (GTK_TYPE_TREE_VIEW, 03633 /* GtkTreeView */ 03634 "enable-search", FALSE, 03635 "headers-visible", FALSE, 03636 "model", dialog->store_unsaved_pages, 03637 NULL)); 03638 renderer = gtk_cell_renderer_toggle_new (); 03639 g_signal_connect (renderer, "toggled", 03640 G_CALLBACK ( 03641 close_confirmation_dialog_callback_renderer_toggled), 03642 dialog); 03643 column = gtk_tree_view_column_new_with_attributes ("Save?", 03644 renderer, 03645 "active", COLUMN_SAVE, 03646 NULL); 03647 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); 03648 03649 renderer = gtk_cell_renderer_text_new (); 03650 column = GTK_TREE_VIEW_COLUMN ( 03651 g_object_new (GTK_TYPE_TREE_VIEW_COLUMN, 03652 /* GtkTreeViewColumn */ 03653 "title", _("Name"), 03654 NULL)); 03655 gtk_tree_view_column_pack_start (column, renderer, TRUE); 03656 gtk_tree_view_column_set_cell_data_func (column, renderer, 03657 close_confirmation_dialog_set_page_name, 03658 NULL, NULL); 03659 gtk_tree_view_append_column (GTK_TREE_VIEW (treeview), column); 03660 03661 gtk_container_add (GTK_CONTAINER (scrolled_window), treeview); 03662 03663 gtk_box_pack_end (GTK_BOX (vbox), scrolled_window, 03664 TRUE, TRUE, 0); 03665 03666 /* the caption label above the list of pages */ 03667 label = GTK_WIDGET (g_object_new (GTK_TYPE_LABEL, 03668 /* GtkMisc */ 03669 "xalign", 0.0, 03670 "yalign", 0.0, 03671 /* GtkLabel */ 03672 "wrap", TRUE, 03673 "mnemonic-widget", treeview, 03674 NULL)); 03675 text = _("S_elect the schematics you want to save:"); 03676 gtk_label_set_text_with_mnemonic (GTK_LABEL (label), text); 03677 gtk_label_set_mnemonic_widget (GTK_LABEL (label), treeview); 03678 gtk_box_pack_start (GTK_BOX (vbox), label, 03679 FALSE, FALSE, 0); 03680 03681 return vbox; 03682 } 03683 03684 static GObject* 03685 close_confirmation_dialog_constructor (GType type, 03686 guint n_construct_properties, 03687 GObjectConstructParam *construct_params) 03688 { 03689 GObject *object; 03690 CloseConfirmationDialog *dialog; 03691 GtkWidget *hbox, *image, *vbox, *label; 03692 GtkTreeIter iter; 03693 gboolean ret, single_page; 03694 gchar *tmp, *str; 03695 const gchar *cstr; 03696 03697 /* chain up to constructor of parent class */ 03698 object = 03699 G_OBJECT_CLASS (close_confirmation_dialog_parent_class)->constructor ( 03700 type, 03701 n_construct_properties, 03702 construct_params); 03703 dialog = CLOSE_CONFIRMATION_DIALOG (object); 03704 03705 g_object_set (dialog, 03706 /* GtkDialog */ 03707 "has-separator", FALSE, 03708 /* GtkWindow */ 03709 "resizable", FALSE, 03710 "skip-taskbar-hint", TRUE, 03711 /* GtkContainer */ 03712 "border-width", 5, 03713 NULL); 03714 g_object_set (GTK_DIALOG (dialog)->vbox, 03715 /* GtkBox */ 03716 "spacing", 14, 03717 NULL); 03718 g_object_set (GTK_DIALOG (dialog)->action_area, 03719 /* GtkBox */ 03720 "spacing", 6, 03721 /* GtkContainer */ 03722 "border-width", 5, 03723 NULL); 03724 03725 /* check if there is one or more than one page with changes */ 03726 ret = gtk_tree_model_get_iter_first (GTK_TREE_MODEL ( 03727 dialog->store_unsaved_pages), 03728 &iter); 03729 g_assert (ret); 03730 single_page = !gtk_tree_model_iter_next (GTK_TREE_MODEL ( 03731 dialog->store_unsaved_pages), 03732 &iter); 03733 03734 /* here starts the layout of the dialog */ 03735 hbox = GTK_WIDGET (g_object_new (GTK_TYPE_HBOX, 03736 /* GtkContainer */ 03737 "border-width", 5, 03738 /* GtkBox */ 03739 "homogeneous", FALSE, 03740 "spacing", 12, 03741 NULL)); 03742 03743 /* warning image */ 03744 image = g_object_new (GTK_TYPE_IMAGE, 03745 /* GtkMisc */ 03746 "xalign", 0.5, 03747 "yalign", 0.0, 03748 /* GtkImage */ 03749 "stock", GTK_STOCK_DIALOG_WARNING, 03750 "icon-size", GTK_ICON_SIZE_DIALOG, 03751 NULL); 03752 gtk_box_pack_start (GTK_BOX (hbox), image, 03753 FALSE, FALSE, 0); 03754 03755 /* vertical box on the right hand side of the dialog */ 03756 vbox = GTK_WIDGET (g_object_new (GTK_TYPE_VBOX, 03757 /* GtkBox */ 03758 "homogeneous", FALSE, 03759 "spacing", 12, 03760 NULL)); 03761 03762 /* primary label */ 03763 if (single_page) { 03764 /* single page */ 03765 gchar *page_name; 03766 03767 page_name = get_page_name (GTK_TREE_MODEL (dialog->store_unsaved_pages), 03768 NULL); 03769 tmp = g_strdup_printf ( 03770 _("Save the changes to schematic \"%s\" before closing?"), 03771 page_name); 03772 g_free (page_name); 03773 } else { 03774 /* multi page */ 03775 tmp = g_strdup_printf ( 03776 _("There are %d schematics with unsaved changes. " 03777 "Save changes before closing?"), 03778 count_pages (GTK_TREE_MODEL (dialog->store_unsaved_pages))); 03779 } 03780 str = g_strconcat ("<big><b>", tmp, "</b></big>", NULL); 03781 g_free (tmp); 03782 label = GTK_WIDGET (g_object_new (GTK_TYPE_LABEL, 03783 /* GtkMisc */ 03784 "xalign", 0.0, 03785 "yalign", 0.0, 03786 "selectable", TRUE, 03787 /* GtkLabel */ 03788 "wrap", TRUE, 03789 "use-markup", TRUE, 03790 "label", str, 03791 NULL)); 03792 g_free (str); 03793 gtk_box_pack_start (GTK_BOX (vbox), label, 03794 FALSE, FALSE, 0); 03795 03796 if (!single_page) { 03797 /* more than one page with changes, display each page and offer */ 03798 /* the opportunity to save them before exiting */ 03799 gtk_box_pack_start (GTK_BOX (vbox), 03800 close_confirmation_dialog_build_page_list (dialog), 03801 FALSE, FALSE, 0); 03802 } 03803 03804 /* secondary label */ 03805 cstr = _("If you don't save, all your changes will be permanently lost."); 03806 label = GTK_WIDGET (g_object_new (GTK_TYPE_LABEL, 03807 /* GtkMisc */ 03808 "xalign", 0.0, 03809 "yalign", 0.0, 03810 "selectable", TRUE, 03811 /* GtkLabel */ 03812 "wrap", TRUE, 03813 "label", cstr, 03814 NULL)); 03815 gtk_box_pack_start (GTK_BOX (vbox), label, 03816 FALSE, FALSE, 0); 03817 03818 03819 gtk_box_pack_start (GTK_BOX (hbox), vbox, 03820 FALSE, FALSE, 0); 03821 03822 03823 /* add buttons to dialog action area */ 03824 gtk_dialog_add_buttons (GTK_DIALOG (dialog), 03825 _("_Close without saving"), GTK_RESPONSE_NO, 03826 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, 03827 GTK_STOCK_SAVE, GTK_RESPONSE_YES, 03828 NULL); 03829 03830 /* Set the alternative button order (ok, cancel, help) for other systems */ 03831 gtk_dialog_set_alternative_button_order(GTK_DIALOG(dialog), 03832 GTK_RESPONSE_YES, 03833 GTK_RESPONSE_NO, 03834 GTK_RESPONSE_CANCEL, 03835 -1); 03836 03837 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_YES); 03838 03839 /* all done, let's show the contents of the dialog */ 03840 gtk_widget_show_all (hbox); 03841 03842 gtk_box_pack_start (GTK_BOX (GTK_DIALOG (dialog)->vbox), hbox, 03843 FALSE, FALSE, 0); 03844 03845 return object; 03846 } 03847 03848 static void 03849 close_confirmation_dialog_set_property (GObject *object, 03850 guint property_id, 03851 const GValue *value, 03852 GParamSpec *pspec) 03853 { 03854 CloseConfirmationDialog *dialog = CLOSE_CONFIRMATION_DIALOG (object); 03855 GtkTreeIter iter; 03856 gpointer data; 03857 GList *p_current; 03858 03859 switch(property_id) { 03860 case PROP_UNSAVED_PAGE: 03861 data = g_value_get_pointer (value); 03862 if (data != NULL) { 03863 /* add single page to model */ 03864 gtk_list_store_append (dialog->store_unsaved_pages, 03865 &iter); 03866 gtk_list_store_set (dialog->store_unsaved_pages, 03867 &iter, 03868 COLUMN_SAVE, TRUE, 03869 COLUMN_PAGE, data, 03870 -1); 03871 } 03872 break; 03873 03874 case PROP_UNSAVED_PAGES: 03875 data = g_value_get_pointer (value); 03876 /* add set of pages to model */ 03877 for (p_current = (GList*)data; 03878 p_current != NULL; 03879 p_current = g_list_next (p_current)) { 03880 gtk_list_store_append (dialog->store_unsaved_pages, 03881 &iter); 03882 gtk_list_store_set (dialog->store_unsaved_pages, 03883 &iter, 03884 COLUMN_SAVE, TRUE, 03885 COLUMN_PAGE, p_current->data, 03886 -1); 03887 } 03888 break; 03889 03890 default: 03891 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); 03892 } 03893 03894 } 03895 03896 static void 03897 close_confirmation_dialog_get_property (GObject *object, 03898 guint property_id, 03899 GValue *value, 03900 GParamSpec *pspec) 03901 { 03902 CloseConfirmationDialog *dialog = CLOSE_CONFIRMATION_DIALOG (object); 03903 03904 switch(property_id) { 03905 case PROP_SELECTED_PAGES: 03906 g_value_set_pointer ( 03907 value, 03908 close_confirmation_dialog_get_selected_pages (dialog)); 03909 break; 03910 03911 default: 03912 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec); 03913 } 03914 03915 } 03916 03932 static gboolean 03933 get_selected_pages (GtkTreeModel *model, 03934 GtkTreePath *path, 03935 GtkTreeIter *iter, 03936 gpointer data) 03937 { 03938 PAGE *page; 03939 gboolean save; 03940 03941 gtk_tree_model_get (model, iter, 03942 COLUMN_SAVE, &save, 03943 COLUMN_PAGE, &page, 03944 -1); 03945 if (save) { 03946 g_assert (page != NULL); 03947 *(GList**)data = g_list_append (*(GList**)data, page); 03948 } 03949 03950 return FALSE; 03951 } 03952 03963 GList* 03964 close_confirmation_dialog_get_selected_pages (CloseConfirmationDialog *dialog) 03965 { 03966 GList *selected = NULL; 03967 03968 gtk_tree_model_foreach (GTK_TREE_MODEL (dialog->store_unsaved_pages), 03969 (GtkTreeModelForeachFunc)get_selected_pages, 03970 &selected); 03971 03972 return selected; 03973 } 03974 03975 03988 void 03989 x_dialog_close_changed_page (GSCHEM_TOPLEVEL *w_current, PAGE *page) 03990 { 03991 GtkWidget *dialog; 03992 PAGE *keep_page; 03993 03994 g_return_if_fail (page != NULL && page->CHANGED); 03995 03996 keep_page = w_current->toplevel->page_current; 03997 03998 dialog = GTK_WIDGET (g_object_new (TYPE_CLOSE_CONFIRMATION_DIALOG, 03999 "unsaved-page", page, 04000 NULL)); 04001 /* set default response signal. This is usually triggered by the 04002 "Return" key */ 04003 gtk_dialog_set_default_response(GTK_DIALOG(dialog), 04004 GTK_RESPONSE_YES); 04005 04006 switch (gtk_dialog_run (GTK_DIALOG (dialog))) { 04007 case GTK_RESPONSE_NO: 04008 /* action selected: close without saving */ 04009 /* close the page, discard changes */ 04010 x_window_close_page (w_current, page); 04011 break; 04012 04013 04014 case GTK_RESPONSE_YES: 04015 /* action selected: save */ 04016 s_page_goto (w_current->toplevel, page); 04017 i_callback_file_save(w_current, 0, NULL); 04018 /* has the page been really saved? */ 04019 if (!page->CHANGED) { 04020 x_window_close_page (w_current, page); 04021 } 04022 /* no, user has cancelled the save and page has changes */ 04023 /* do not close page */ 04024 break; 04025 04026 case GTK_RESPONSE_CANCEL: 04027 /* action selected: cancel */ 04028 /* fall through */ 04029 default: 04030 /* Hit when the user breaks out of the dialog with the escape key 04031 * or otherwise destroys the dialog window without a proper response */ 04032 /* nothing to do */ 04033 break; 04034 } 04035 gtk_widget_destroy (dialog); 04036 04037 /* Switch back to the page we were on if it wasn't the one being closed */ 04038 g_return_if_fail (keep_page != NULL); 04039 if (keep_page != page) 04040 s_page_goto (w_current->toplevel, keep_page); 04041 } 04042 04058 gboolean 04059 x_dialog_close_window (GSCHEM_TOPLEVEL *w_current) 04060 { 04061 TOPLEVEL *toplevel = w_current->toplevel; 04062 GList *iter; 04063 GtkWidget *dialog; 04064 PAGE *p_current; 04065 PAGE *keep_page; 04066 GList *unsaved_pages, *p_unsaved; 04067 gboolean ret = FALSE; 04068 04069 keep_page = toplevel->page_current; 04070 04071 for ( iter = geda_list_get_glist( toplevel->pages ), unsaved_pages = NULL; 04072 iter != NULL; 04073 iter = g_list_next( iter ) ) { 04074 04075 p_current = (PAGE*)iter->data; 04076 04077 if (p_current->CHANGED) { 04078 unsaved_pages = g_list_append (unsaved_pages, (gpointer)p_current); 04079 } 04080 } 04081 04082 if (unsaved_pages == NULL) { 04083 /* no page with unsaved changes, close window */ 04084 return TRUE; 04085 } 04086 04087 dialog = GTK_WIDGET (g_object_new (TYPE_CLOSE_CONFIRMATION_DIALOG, 04088 "unsaved-pages", unsaved_pages, 04089 NULL)); 04090 04091 gtk_window_set_transient_for (GTK_WINDOW (dialog), 04092 GTK_WINDOW (w_current->main_window)); 04093 04094 g_list_free (unsaved_pages); 04095 switch (gtk_dialog_run (GTK_DIALOG (dialog))) { 04096 case GTK_RESPONSE_NO: 04097 /* action selected: close without saving */ 04098 /* discard changes, ok to close window */ 04099 ret = TRUE; 04100 break; 04101 04102 case GTK_RESPONSE_YES: 04103 /* action selected: save */ 04104 g_object_get (dialog, 04105 "selected-pages", &unsaved_pages, 04106 NULL); 04107 for (p_unsaved = unsaved_pages, ret = TRUE; 04108 p_unsaved != NULL; 04109 p_unsaved = g_list_next (p_unsaved)) { 04110 p_current = (PAGE*)p_unsaved->data; 04111 04112 s_page_goto (toplevel, p_current); 04113 i_callback_file_save(w_current, 0, NULL); 04114 /* if user cancelled previous, do not close window */ 04115 ret &= !p_current->CHANGED; 04116 } 04117 g_list_free (unsaved_pages); 04118 break; 04119 04120 case GTK_RESPONSE_CANCEL: 04121 /* action selected: cancel */ 04122 /* fall through */ 04123 default: 04124 /* Hit when the user breaks out of the dialog with the escape key 04125 * or otherwise destroys the dialog window without a proper response */ 04126 ret = FALSE; 04127 break; 04128 } 04129 gtk_widget_destroy (dialog); 04130 04131 /* Switch back to the page we were on */ 04132 g_return_val_if_fail (keep_page != NULL, ret); 04133 s_page_goto (toplevel, keep_page); 04134 04135 return ret; 04136 } 04137 04138 /***************** End of Close Confirmation dialog box **************/ 04139 04140 04141 /***************** Start of misc helper dialog boxes **************/ 04151 int x_dialog_validate_attribute(GtkWindow* parent, char *attribute) 04152 { 04153 GtkWidget* message_box; 04154 04155 /* validate the new attribute */ 04156 if (!o_attrib_string_get_name_value (attribute, NULL, NULL)) { 04157 message_box = gtk_message_dialog_new_with_markup (parent, 04158 GTK_DIALOG_DESTROY_WITH_PARENT, 04159 GTK_MESSAGE_ERROR, 04160 GTK_BUTTONS_CLOSE, 04161 _("<span weight=\"bold\" size=\"larger\">The input attribute \"%s\" is invalid\nPlease correct in order to continue</span>\n\nThe name and value must be non-empty.\nThe name cannot end with a space.\nThe value cannot start with a space."), 04162 attribute); 04163 gtk_window_set_title(GTK_WINDOW(message_box), _("Invalid Attribute")); 04164 gtk_dialog_run (GTK_DIALOG (message_box)); 04165 gtk_widget_destroy (message_box); 04166 return FALSE; 04167 } 04168 return TRUE; 04169 } 04170 /***************** End of misc helper dialog boxes **************/ 04171 04177 void x_dialog_edit_pin_type (GSCHEM_TOPLEVEL *w_current, const GList *obj_list) 04178 { 04179 GtkWidget *dialog; 04180 GtkWidget *vbox; 04181 GtkWidget *radio1; 04182 GtkWidget *radio2; 04183 const GList *iter; 04184 int new_type; 04185 int found_pins = FALSE; 04186 int changed_anything = FALSE; 04187 04188 for (iter = obj_list; iter != NULL; iter = g_list_next (iter)) { 04189 OBJECT *object = iter->data; 04190 if (object->type == OBJ_PIN) { 04191 found_pins = TRUE; 04192 break; 04193 } 04194 } 04195 04196 if (!found_pins) 04197 return; 04198 04199 dialog = gschem_dialog_new_with_buttons(_("Pin type"), 04200 GTK_WINDOW(w_current->main_window), 04201 GTK_DIALOG_MODAL, 04202 "pin-type-edit", w_current, 04203 GTK_STOCK_CANCEL, 04204 GTK_RESPONSE_CANCEL, 04205 GTK_STOCK_OK, 04206 GTK_RESPONSE_OK, 04207 NULL); 04208 04209 /* Set the alternative button order (ok, cancel, help) for other systems */ 04210 gtk_dialog_set_alternative_button_order (GTK_DIALOG (dialog), 04211 GTK_RESPONSE_OK, 04212 GTK_RESPONSE_CANCEL, 04213 -1); 04214 04215 gtk_window_position (GTK_WINDOW (dialog), GTK_WIN_POS_MOUSE); 04216 04217 gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL); 04218 04219 gtk_container_border_width (GTK_CONTAINER (dialog), DIALOG_BORDER_SPACING); 04220 vbox = GTK_DIALOG (dialog)->vbox; 04221 gtk_box_set_spacing (GTK_BOX(vbox), DIALOG_V_SPACING); 04222 04223 radio1 = gtk_radio_button_new_with_label (NULL, _("Net pin")); 04224 radio2 = gtk_radio_button_new_with_label_from_widget (GTK_RADIO_BUTTON (radio1), 04225 _("Bus pin (graphical)")); 04226 /* Pack them into a box, then show all the widgets */ 04227 gtk_box_pack_start (GTK_BOX (vbox), radio1, TRUE, TRUE, 2); 04228 gtk_box_pack_start (GTK_BOX (vbox), radio2, TRUE, TRUE, 2); 04229 gtk_widget_show_all (vbox); 04230 04231 switch (gtk_dialog_run (GTK_DIALOG (dialog))) { 04232 case GTK_RESPONSE_OK: 04233 new_type = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (radio1)) ? 04234 PIN_TYPE_NET : PIN_TYPE_BUS; 04235 for (iter = obj_list; iter != NULL; iter = g_list_next (iter)) { 04236 OBJECT *object = iter->data; 04237 04238 if (object->type == OBJ_PIN && 04239 object->pin_type != new_type) { 04240 changed_anything = TRUE; 04241 s_conn_remove_object (w_current->toplevel, object); 04242 o_pin_set_type (w_current->toplevel, object, new_type); 04243 s_conn_update_object (w_current->toplevel, object); 04244 } 04245 } 04246 if (changed_anything) 04247 o_undo_savestate (w_current, UNDO_ALL); 04248 break; 04249 04250 case GTK_RESPONSE_CANCEL: 04251 default: 04252 /* Do nothing */ 04253 break; 04254 } 04255 04256 gtk_widget_destroy (dialog); 04257 } 04258 04259 /***************** End of pin type edit dialog box *********************/