edit_gtk.c
1 /* Classic Ladder Project */ 2 /* Copyright (C) 2001-2007 Marc Le Douarain */ 3 /* http://membres.lycos.fr/mavati/classicladder/ */ 4 /* http://www.sourceforge.net/projects/classicladder */ 5 /* May 2001 */ 6 /* --------------------------- */ 7 /* Editor - GTK interface part */ 8 /* --------------------------- */ 9 /* This library is free software; you can redistribute it and/or */ 10 /* modify it under the terms of the GNU Lesser General Public */ 11 /* License as published by the Free Software Foundation; either */ 12 /* version 2.1 of the License, or (at your option) any later version. */ 13 14 /* This library is distributed in the hope that it will be useful, */ 15 /* but WITHOUT ANY WARRANTY; without even the implied warranty of */ 16 /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */ 17 /* Lesser General Public License for more details. */ 18 19 /* You should have received a copy of the GNU Lesser General Public */ 20 /* License along with this library; if not, write to the Free Software */ 21 /* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ 22 23 #include <locale.h> 24 #include <libintl.h> 25 #define _(x) gettext(x) 26 #include <gtk/gtk.h> 27 #include <stdio.h> 28 #include "classicladder.h" 29 #include "global.h" 30 #include "drawing.h" 31 #include "edit.h" 32 #include "classicladder_gtk.h" 33 #include "edit_gtk.h" 34 #include "editproperties_gtk.h" 35 36 static GtkWidget *EditorButtonOk,*EditorButtonCancel; 37 static GtkWidget *EditorButtonAdd,*EditorButtonIns,*EditorButtonDel; 38 static GtkWidget *EditorButtonModify; 39 40 #define NBR_ELE_IN_TOOLBAR 50 41 #define NBR_ELE_TOOLBAR_Y_MAX 15 // used for each GtkTable 42 #define NBR_ELE_TOOLBAR_X_MAX 4 43 static GtkWidget * ToolbarBtnRadio[ NBR_ELE_IN_TOOLBAR ]; 44 static GtkWidget * ToolbarImage[ NBR_ELE_IN_TOOLBAR ]; 45 static GdkPixmap * ToolbarPixmap[ NBR_ELE_IN_TOOLBAR ]; 46 #define NUM_TOOLBAR_FOR_RUNGS 0 47 #define NUM_TOOLBAR_FOR_SEQ 1 48 static GtkWidget * ToolbarTable[ 2 ]; 49 static int NumWidgetEditPointer[ 2 ]; 50 GtkTooltips * TheTooltips; 51 52 #define PIXELS_SIZE_IN_TOOLBAR 32 53 54 static short int ToolBarElementsLadder[ ][NBR_ELE_TOOLBAR_X_MAX] = 55 { {EDIT_POINTER , EDIT_ERASER, 0 , 0} , 56 {ELE_INPUT , ELE_INPUT_NOT , ELE_RISING_INPUT , ELE_FALLING_INPUT} , 57 {ELE_CONNECTION , EDIT_CNX_WITH_TOP, EDIT_LONG_CONNECTION , 0} , 58 {ELE_TIMER_IEC , ELE_COUNTER , ELE_COMPAR , 0} , 59 #ifdef OLD_TIMERS_MONOS_SUPPORT 60 {ELE_TIMER , ELE_MONOSTABLE , 0 , 0} , 61 #endif 62 {ELE_OUTPUT , ELE_OUTPUT_NOT, ELE_OUTPUT_SET , ELE_OUTPUT_RESET} , 63 {ELE_OUTPUT_JUMP, ELE_OUTPUT_CALL , ELE_OUTPUT_OPERATE , 0} , 64 {-1,-1}/*end*/ }; 65 char * ToolBarToolTipsTextLadder[ ][NBR_ELE_TOOLBAR_X_MAX] = 66 { { "Object\nSelector", "Eraser", NULL, NULL }, 67 { "N.O. Input", "N.C. Input", "Rising Edge\n Input", "Falling Edge\n Input" }, 68 { "Horizontal\nConnection", "Vertical\nConnection", "Long Horizontal\nConnection", NULL }, 69 { "Timer IEC Block", "Counter Block", "Variable\nComparison", NULL }, 70 #ifdef OLD_TIMERS_MONOS_SUPPORT 71 { "Old Timer Block", "Monostable Block", NULL, NULL }, 72 #endif 73 { "N.O. Output", "N.C. Output", "Set Output", "Reset Output" }, 74 { "Jump Coil", "Call Coil", "Variable\nAssignment", NULL }, 75 { NULL, NULL, NULL, NULL } }; 76 77 78 #ifdef SEQUENTIAL_SUPPORT 79 #include "drawing_sequential.h" 80 #include "edit_sequential.h" 81 static short int ToolBarElementsSequential[ ][NBR_ELE_TOOLBAR_X_MAX] = 82 { {EDIT_POINTER , EDIT_ERASER , 0 , 0} , 83 {ELE_SEQ_STEP , EDIT_SEQ_INIT_STEP , 0 , 0} , 84 {ELE_SEQ_TRANSITION , EDIT_SEQ_STEP_AND_TRANS , 0 , 0} , 85 {EDIT_SEQ_START_MANY_TRANS , EDIT_SEQ_END_MANY_TRANS , 0 , 0} , 86 {EDIT_SEQ_START_MANY_STEPS , EDIT_SEQ_END_MANY_STEPS , 0 , 0} , 87 {EDIT_SEQ_LINK , 0 , 0 , 0} , 88 {ELE_SEQ_COMMENT , 0 , 0 , 0} , 89 {-1,-1}/*end*/ }; 90 char * ToolBarToolTipsTextSequential[ ][NBR_ELE_TOOLBAR_X_MAX] = 91 { { "Current Object\nSelector", "Eraser", NULL, NULL }, 92 { "Step", NULL, NULL, NULL }, 93 { "Transition", NULL, NULL, NULL }, 94 { NULL, NULL, NULL, NULL }, 95 { NULL, NULL, NULL, NULL }, 96 { "Link", NULL, NULL, NULL }, 97 { "Comment", NULL, NULL, NULL }, 98 { NULL, NULL, NULL, NULL } }; 99 #endif 100 101 GtkWidget *EditWindow; 102 103 104 void ButtonsForStart() 105 { 106 int iCurrentLanguage = SectionArray[ InfosGene->CurrentSection ].Language; 107 gtk_widget_hide (EditorButtonAdd); 108 gtk_widget_hide (EditorButtonIns); 109 gtk_widget_hide (EditorButtonDel); 110 gtk_widget_hide (EditorButtonModify); 111 gtk_widget_show (EditorButtonOk); 112 gtk_widget_show (EditorButtonCancel); 113 ShowPropertiesWindow( TRUE ); 114 // select directly the pointer in toolbar per default... 115 EditDatas.NumElementSelectedInToolBar = EDIT_POINTER; 116 // ...in rung toolbar 117 if ( NumWidgetEditPointer[ NUM_TOOLBAR_FOR_RUNGS ]!=-1 ) 118 { 119 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(ToolbarBtnRadio[ NumWidgetEditPointer[ NUM_TOOLBAR_FOR_RUNGS ] ]), TRUE ); 120 gtk_widget_set_sensitive( ToolbarTable[ NUM_TOOLBAR_FOR_RUNGS ], TRUE ); 121 } 122 // ...in sequential toolbar 123 if ( NumWidgetEditPointer[ NUM_TOOLBAR_FOR_SEQ ]!=-1 ) 124 { 125 gtk_toggle_button_set_active( GTK_TOGGLE_BUTTON(ToolbarBtnRadio[ NumWidgetEditPointer[ NUM_TOOLBAR_FOR_SEQ ] ]), TRUE ); 126 gtk_widget_set_sensitive( ToolbarTable[ NUM_TOOLBAR_FOR_SEQ ], TRUE ); 127 } 128 MessageInStatusBar( iCurrentLanguage==SECTION_IN_LADDER?_("Current rung in edit mode..."):_("Edit mode...") ); 129 } 130 void ButtonsForEnd( char ForRung ) 131 { 132 if ( ForRung ) 133 { 134 gtk_widget_show (EditorButtonAdd); 135 gtk_widget_show (EditorButtonIns); 136 gtk_widget_show (EditorButtonDel); 137 gtk_widget_set_sensitive( ToolbarTable[ NUM_TOOLBAR_FOR_RUNGS ], FALSE ); 138 } 139 else 140 { 141 gtk_widget_hide (EditorButtonAdd); 142 gtk_widget_hide (EditorButtonIns); 143 gtk_widget_hide (EditorButtonDel); 144 gtk_widget_set_sensitive( ToolbarTable[ NUM_TOOLBAR_FOR_SEQ ], FALSE ); 145 } 146 gtk_widget_show (EditorButtonModify); 147 gtk_widget_hide (EditorButtonOk); 148 gtk_widget_hide (EditorButtonCancel); 149 ShowPropertiesWindow( FALSE ); 150 MessageInStatusBar( "" ); 151 } 152 153 void EditorButtonsAccordingSectionType( ) 154 { 155 int iCurrentLanguage = SectionArray[ InfosGene->CurrentSection ].Language; 156 // if under edit, cancel current operation 157 if ( EditDatas.ModeEdit ) 158 ButtonCancelCurrentRung( ); 159 #ifdef SEQUENTIAL_SUPPORT 160 if ( iCurrentLanguage==SECTION_IN_SEQUENTIAL ) 161 { 162 gtk_widget_hide( ToolbarTable[ NUM_TOOLBAR_FOR_RUNGS ] ); 163 gtk_widget_show( ToolbarTable[ NUM_TOOLBAR_FOR_SEQ ] ); 164 } 165 else 166 { 167 gtk_widget_hide( ToolbarTable[ NUM_TOOLBAR_FOR_SEQ ] ); 168 gtk_widget_show( ToolbarTable[ NUM_TOOLBAR_FOR_RUNGS ] ); 169 } 170 #endif 171 MessageInStatusBar( "" ); 172 } 173 174 void ButtonAddRung() 175 { 176 AddRung(); 177 ButtonsForStart(); 178 } 179 void ButtonInsertRung() 180 { 181 InsertRung(); 182 ButtonsForStart(); 183 } 184 void ButtonDeleteCurrentRung() 185 { 186 ShowConfirmationBox(_("Delete"),_("Do you really want to delete the current rung ?"),DeleteCurrentRung); 187 } 188 void ButtonModifyCurrentRung() 189 { 190 int iCurrentLanguage = SectionArray[ InfosGene->CurrentSection ].Language; 191 if ( iCurrentLanguage==SECTION_IN_LADDER ) 192 { 193 ModifyCurrentRung(); 194 ButtonsForStart(); 195 } 196 #ifdef SEQUENTIAL_SUPPORT 197 if ( iCurrentLanguage==SECTION_IN_SEQUENTIAL ) 198 { 199 ModifyCurrentSeqPage(); 200 ButtonsForStart(); 201 } 202 #endif 203 } 204 void ButtonOkCurrentRung() 205 { 206 int iCurrentLanguage = SectionArray[ InfosGene->CurrentSection ].Language; 207 if ( iCurrentLanguage==SECTION_IN_LADDER ) 208 ApplyRungEdited(); 209 #ifdef SEQUENTIAL_SUPPORT 210 if ( iCurrentLanguage==SECTION_IN_SEQUENTIAL ) 211 ApplySeqPageEdited(); 212 #endif 213 ButtonsForEnd( iCurrentLanguage==SECTION_IN_LADDER ); 214 } 215 void ButtonCancelCurrentRung() 216 { 217 int iCurrentLanguage = SectionArray[ InfosGene->CurrentSection ].Language; 218 if ( iCurrentLanguage==SECTION_IN_LADDER ) 219 CancelRungEdited(); 220 #ifdef SEQUENTIAL_SUPPORT 221 if ( iCurrentLanguage==SECTION_IN_SEQUENTIAL ) 222 CancelSeqPageEdited(); 223 #endif 224 ButtonsForEnd( iCurrentLanguage==SECTION_IN_LADDER ); 225 } 226 227 gint EditorWindowDeleteEvent( GtkWidget * widget, GdkEvent * event, gpointer data ) 228 { 229 gtk_widget_hide( EditWindow ); 230 // we do not want that the window be destroyed. 231 return TRUE; 232 } 233 234 void OpenEditWindow( void ) 235 { 236 if ( !GTK_WIDGET_VISIBLE( EditWindow ) ) 237 { 238 gtk_widget_show (EditWindow); 239 #ifdef GTK2 240 gtk_window_present( GTK_WINDOW(EditWindow) ); 241 #endif 242 } 243 else 244 { 245 gtk_widget_hide( EditWindow ); 246 } 247 } 248 249 void ButtonToolbarSignal( GtkWidget * widget, gpointer data ) 250 { 251 EditDatas.NumElementSelectedInToolBar = GPOINTER_TO_INT( data ); 252 } 253 254 void InitAllForToolbar( void ) 255 { 256 int Search = 0; 257 for ( Search=0; Search<NBR_ELE_IN_TOOLBAR; Search++ ) 258 { 259 ToolbarBtnRadio[ Search ] = NULL; 260 ToolbarImage[ Search ] = NULL; 261 ToolbarPixmap[ Search ] = NULL; 262 } 263 NumWidgetEditPointer[ NUM_TOOLBAR_FOR_RUNGS ] = -1; 264 NumWidgetEditPointer[ NUM_TOOLBAR_FOR_SEQ ] = -1; 265 } 266 267 void CreateOneToolbar( GtkWidget * Box, int NumTable, short int PtrOnToolBarElementsList[][NBR_ELE_TOOLBAR_X_MAX], char * PtrOnToolTipsText[][NBR_ELE_TOOLBAR_X_MAX] ) 268 { 269 int CurrentAvail = 0; 270 while( ToolbarBtnRadio[ CurrentAvail ]!=NULL && CurrentAvail<NBR_ELE_IN_TOOLBAR ) 271 CurrentAvail++; 272 if ( CurrentAvail<NBR_ELE_IN_TOOLBAR ) 273 { 274 StrElement ToolBarEle; 275 int ScanToolBarX,ScanToolBarY; 276 GSList * PtrListRadiosBtn = NULL; 277 ScanToolBarX = 0; 278 ScanToolBarY = 0; 279 ToolbarTable[ NumTable ] = gtk_table_new( NBR_ELE_TOOLBAR_X_MAX, NBR_ELE_TOOLBAR_Y_MAX, FALSE/*homogeneous*/ ); 280 gtk_box_pack_start (GTK_BOX(Box), ToolbarTable[ NumTable ], TRUE, TRUE, 0); 281 do 282 { 283 ToolBarEle.Type = PtrOnToolBarElementsList[ScanToolBarY][ScanToolBarX]; 284 ToolBarEle.ConnectedWithTop = 0; 285 if ( ToolBarEle.Type==EDIT_POINTER ) 286 { 287 if ( PtrOnToolBarElementsList!=ToolBarElementsSequential ) 288 NumWidgetEditPointer[ NUM_TOOLBAR_FOR_RUNGS ] = CurrentAvail; 289 else 290 NumWidgetEditPointer[ NUM_TOOLBAR_FOR_SEQ ] = CurrentAvail; 291 } 292 293 if ( ToolBarEle.Type!=0 ) 294 { 295 GdkGC * gc = drawing_area->style->bg_gc[0]; 296 char * pHelpText = PtrOnToolTipsText[ ScanToolBarY ][ ScanToolBarX ]; 297 ToolbarPixmap[ CurrentAvail ] = gdk_pixmap_new( GDK_DRAWABLE(drawing_area->window), PIXELS_SIZE_IN_TOOLBAR, PIXELS_SIZE_IN_TOOLBAR, -1 ); 298 gdk_draw_rectangle (GDK_DRAWABLE(ToolbarPixmap[ CurrentAvail ]), gc, TRUE, 0, 0, PIXELS_SIZE_IN_TOOLBAR, PIXELS_SIZE_IN_TOOLBAR); 299 300 #ifdef SEQUENTIAL_SUPPORT 301 if ( PtrOnToolBarElementsList==ToolBarElementsSequential ) 302 DrawSeqElementForToolBar(ToolbarPixmap[ CurrentAvail ], 0, 0, PIXELS_SIZE_IN_TOOLBAR, ToolBarEle.Type ); 303 else 304 #endif 305 DrawElement(ToolbarPixmap[ CurrentAvail ], 0, 0, PIXELS_SIZE_IN_TOOLBAR, PIXELS_SIZE_IN_TOOLBAR, ToolBarEle, TRUE); 306 307 ToolbarImage[ CurrentAvail ] = gtk_image_new_from_pixmap( ToolbarPixmap[ CurrentAvail ], NULL ); 308 ToolbarBtnRadio[ CurrentAvail ] = gtk_radio_button_new( PtrListRadiosBtn ); 309 PtrListRadiosBtn = gtk_radio_button_get_group (GTK_RADIO_BUTTON(ToolbarBtnRadio[ CurrentAvail ])); 310 gtk_button_set_relief (GTK_BUTTON( ToolbarBtnRadio[ CurrentAvail ] ), GTK_RELIEF_NONE); 311 gtk_toggle_button_set_mode (GTK_TOGGLE_BUTTON(ToolbarBtnRadio[ CurrentAvail ]), FALSE); 312 gtk_container_add( GTK_CONTAINER( ToolbarBtnRadio[ CurrentAvail ] ), ToolbarImage[ CurrentAvail ] ); 313 gtk_widget_show( ToolbarImage[ CurrentAvail ] ); 314 gtk_table_attach( GTK_TABLE( ToolbarTable[ NumTable ] ), ToolbarBtnRadio[ CurrentAvail ], 315 ScanToolBarX, ScanToolBarX+1, ScanToolBarY, ScanToolBarY+1, 316 0, 0, 0, 0 ); 317 318 gtk_signal_connect( GTK_OBJECT (ToolbarBtnRadio[ CurrentAvail ]), "clicked", (GtkSignalFunc) ButtonToolbarSignal, GINT_TO_POINTER((int)ToolBarEle.Type) ); 319 320 if (pHelpText!=NULL ) 321 gtk_tooltips_set_tip (TheTooltips, ToolbarBtnRadio[ CurrentAvail ], pHelpText, NULL); 322 323 gtk_widget_show( ToolbarBtnRadio[ CurrentAvail ] ); 324 CurrentAvail++; 325 }//if ( ToolBarEle.Type!=0 ) 326 327 ScanToolBarX++; 328 if (ScanToolBarX>=NBR_ELE_TOOLBAR_X_MAX) 329 { 330 ScanToolBarX = 0; 331 ScanToolBarY++; 332 } 333 } 334 while( PtrOnToolBarElementsList[ScanToolBarY][ScanToolBarX]!=-1 ); 335 } 336 } 337 338 339 void EditorInitGtk() 340 { 341 GtkWidget *vbox; 342 343 EditWindow = gtk_window_new (GTK_WINDOW_TOPLEVEL); 344 gtk_window_set_title ( GTK_WINDOW( EditWindow ), _("Editor")); 345 346 vbox = gtk_vbox_new (FALSE, 0); 347 gtk_container_add (GTK_CONTAINER (EditWindow), vbox); 348 gtk_widget_show (vbox); 349 350 EditorButtonAdd = gtk_button_new_with_label (_("Add")); 351 gtk_box_pack_start (GTK_BOX (vbox), EditorButtonAdd, FALSE, FALSE, 0); 352 gtk_signal_connect(GTK_OBJECT (EditorButtonAdd), "clicked", 353 (GtkSignalFunc) ButtonAddRung, 0); 354 gtk_widget_show (EditorButtonAdd); 355 EditorButtonIns = gtk_button_new_with_label (_("Insert")); 356 gtk_box_pack_start (GTK_BOX (vbox), EditorButtonIns, FALSE, FALSE, 0); 357 gtk_signal_connect(GTK_OBJECT (EditorButtonIns), "clicked", 358 (GtkSignalFunc) ButtonInsertRung, 0); 359 gtk_widget_show (EditorButtonIns); 360 EditorButtonDel = gtk_button_new_with_label (_("Delete")); 361 gtk_box_pack_start (GTK_BOX (vbox), EditorButtonDel, FALSE, FALSE, 0); 362 gtk_signal_connect(GTK_OBJECT (EditorButtonDel), "clicked", 363 (GtkSignalFunc) ButtonDeleteCurrentRung, 0); 364 gtk_widget_show (EditorButtonDel); 365 EditorButtonModify = gtk_button_new_with_label (_("Modify")); 366 gtk_box_pack_start (GTK_BOX (vbox), EditorButtonModify, FALSE, FALSE, 0); 367 gtk_signal_connect(GTK_OBJECT (EditorButtonModify), "clicked", 368 (GtkSignalFunc) ButtonModifyCurrentRung, 0); 369 gtk_widget_show (EditorButtonModify); 370 EditorButtonOk = gtk_button_new_with_label (_("Ok")); 371 gtk_box_pack_start (GTK_BOX (vbox), EditorButtonOk, FALSE, FALSE, 0); 372 gtk_signal_connect(GTK_OBJECT (EditorButtonOk), "clicked", 373 (GtkSignalFunc) ButtonOkCurrentRung, 0); 374 EditorButtonCancel = gtk_button_new_with_label (_("Cancel")); 375 gtk_box_pack_start (GTK_BOX (vbox), EditorButtonCancel, FALSE, FALSE, 0); 376 gtk_signal_connect(GTK_OBJECT (EditorButtonCancel), "clicked", 377 (GtkSignalFunc) ButtonCancelCurrentRung, 0); 378 379 InitAllForToolbar( ); 380 TheTooltips = gtk_tooltips_new(); 381 /* Rungs elements toolbar */ 382 CreateOneToolbar( vbox, NUM_TOOLBAR_FOR_RUNGS, ToolBarElementsLadder, ToolBarToolTipsTextLadder ); 383 gtk_widget_set_sensitive( ToolbarTable[ NUM_TOOLBAR_FOR_RUNGS ], FALSE ); 384 gtk_widget_show( ToolbarTable[ NUM_TOOLBAR_FOR_RUNGS ] ); 385 /* Sequential elements toolbar */ 386 #ifdef SEQUENTIAL_SUPPORT 387 CreateOneToolbar( vbox, NUM_TOOLBAR_FOR_SEQ, ToolBarElementsSequential, ToolBarToolTipsTextSequential ); 388 gtk_widget_set_sensitive( ToolbarTable[ NUM_TOOLBAR_FOR_SEQ ], FALSE ); 389 #endif 390 391 gtk_signal_connect( GTK_OBJECT(EditWindow), "delete_event", 392 (GtkSignalFunc)EditorWindowDeleteEvent, 0 ); 393 394 gtk_window_set_resizable( GTK_WINDOW( EditWindow ), FALSE ); 395 //gtk_widget_show (EditWindow); 396 397 EditDatas.NumElementSelectedInToolBar = -1; 398 } 399